拆分工单押金事务仓储
This commit is contained in:
@@ -10,6 +10,7 @@ export * from './work-order-repo.js'
|
|||||||
export * from './work-order-query-repo.js'
|
export * from './work-order-query-repo.js'
|
||||||
export * from './work-order-management-repo.js'
|
export * from './work-order-management-repo.js'
|
||||||
export * from './work-order-deposit-query-repo.js'
|
export * from './work-order-deposit-query-repo.js'
|
||||||
|
export * from './work-order-deposit-repo.js'
|
||||||
export * from './work-order-event-repo.js'
|
export * from './work-order-event-repo.js'
|
||||||
export * from './work-order-share-repo.js'
|
export * from './work-order-share-repo.js'
|
||||||
export * from './work-category-repo.js'
|
export * from './work-category-repo.js'
|
||||||
|
|||||||
@@ -0,0 +1,244 @@
|
|||||||
|
import { withTransaction } from '../../db/client.js'
|
||||||
|
import {
|
||||||
|
ensureWorkerWalletWithClient,
|
||||||
|
getWorkerWalletWithClient,
|
||||||
|
} from './shared.js'
|
||||||
|
import type { WorkerDepositUnfreezeRow } from './types.js'
|
||||||
|
import type { PoolClient } from 'pg'
|
||||||
|
|
||||||
|
export function resolveOutstandingDepositAmount(
|
||||||
|
totals:
|
||||||
|
| {
|
||||||
|
frozen_amount?: number
|
||||||
|
released_amount?: number
|
||||||
|
deducted_amount?: number
|
||||||
|
}
|
||||||
|
| null
|
||||||
|
| undefined,
|
||||||
|
) {
|
||||||
|
return Math.max(
|
||||||
|
0,
|
||||||
|
Number(totals?.frozen_amount || 0) -
|
||||||
|
Number(totals?.released_amount || 0) -
|
||||||
|
Number(totals?.deducted_amount || 0),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getOutstandingDepositAmountWithClient(
|
||||||
|
client: PoolClient,
|
||||||
|
workerId: number,
|
||||||
|
workOrderId: number,
|
||||||
|
) {
|
||||||
|
const result = await client.query<{
|
||||||
|
frozen_amount: number
|
||||||
|
released_amount: number
|
||||||
|
deducted_amount: number
|
||||||
|
}>(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
COALESCE(SUM(CASE WHEN ledger_type = 'deposit_freeze' THEN ABS(amount) ELSE 0 END), 0)::int AS frozen_amount,
|
||||||
|
COALESCE(SUM(CASE WHEN ledger_type = 'deposit_release' THEN ABS(amount) ELSE 0 END), 0)::int AS released_amount,
|
||||||
|
COALESCE(SUM(CASE WHEN ledger_type = 'deposit_deduction' THEN ABS(amount) ELSE 0 END), 0)::int AS deducted_amount
|
||||||
|
FROM worker_wallet_ledgers
|
||||||
|
WHERE worker_id = $1 AND related_work_order_id = $2
|
||||||
|
`,
|
||||||
|
[workerId, workOrderId],
|
||||||
|
)
|
||||||
|
return resolveOutstandingDepositAmount(result.rows[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function enqueueDepositUnfreezeWithClient(
|
||||||
|
client: PoolClient,
|
||||||
|
input: {
|
||||||
|
workerId: number
|
||||||
|
workOrderId: number
|
||||||
|
amount: number
|
||||||
|
unfreezeDays: number
|
||||||
|
now: string
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
if (input.amount <= 0) return
|
||||||
|
const unfreezeAt = new Date(
|
||||||
|
new Date(input.now).getTime() + input.unfreezeDays * 86_400_000,
|
||||||
|
).toISOString()
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
INSERT INTO worker_deposit_unfreezes (
|
||||||
|
worker_id, work_order_id, amount, unfreeze_at, status, created_at, updated_at
|
||||||
|
) VALUES ($1, $2, $3, $4, 'pending', $5, $5)
|
||||||
|
`,
|
||||||
|
[input.workerId, input.workOrderId, input.amount, unfreezeAt, input.now],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deductPendingDepositUnfreeze(input: {
|
||||||
|
workOrderId: number
|
||||||
|
amount: number
|
||||||
|
note: string
|
||||||
|
now: string
|
||||||
|
}): Promise<{
|
||||||
|
deductedAmount: number
|
||||||
|
failureReason: 'no_pending_deposit' | 'amount_exceeds_pending' | null
|
||||||
|
}> {
|
||||||
|
return withTransaction(async (client) => {
|
||||||
|
const pendingResult = await client.query<WorkerDepositUnfreezeRow>(
|
||||||
|
`
|
||||||
|
SELECT *
|
||||||
|
FROM worker_deposit_unfreezes
|
||||||
|
WHERE work_order_id = $1 AND status = 'pending'
|
||||||
|
ORDER BY unfreeze_at ASC
|
||||||
|
FOR UPDATE
|
||||||
|
`,
|
||||||
|
[input.workOrderId],
|
||||||
|
)
|
||||||
|
const pending = pendingResult.rows
|
||||||
|
if (pending.length === 0) {
|
||||||
|
return { deductedAmount: 0, failureReason: 'no_pending_deposit' }
|
||||||
|
}
|
||||||
|
const totalPending = pending.reduce((sum, row) => sum + Number(row.amount || 0), 0)
|
||||||
|
if (input.amount <= 0 || input.amount > totalPending) {
|
||||||
|
return { deductedAmount: 0, failureReason: 'amount_exceeds_pending' }
|
||||||
|
}
|
||||||
|
|
||||||
|
let remainingToDeduct = input.amount
|
||||||
|
let deductedAmount = 0
|
||||||
|
|
||||||
|
for (const row of pending) {
|
||||||
|
if (remainingToDeduct <= 0) break
|
||||||
|
const rowAmount = Number(row.amount || 0)
|
||||||
|
if (rowAmount <= 0) continue
|
||||||
|
const deductFromRow = Math.min(rowAmount, remainingToDeduct)
|
||||||
|
const isFullyDeducted = deductFromRow >= rowAmount
|
||||||
|
|
||||||
|
if (isFullyDeducted) {
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
UPDATE worker_deposit_unfreezes
|
||||||
|
SET status = 'deducted', updated_at = $1
|
||||||
|
WHERE id = $2
|
||||||
|
`,
|
||||||
|
[input.now, row.id],
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
UPDATE worker_deposit_unfreezes
|
||||||
|
SET amount = amount - $1, updated_at = $2
|
||||||
|
WHERE id = $3
|
||||||
|
`,
|
||||||
|
[deductFromRow, input.now, row.id],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const workerWallet = await getWorkerWalletWithClient(client, row.worker_id)
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
UPDATE worker_wallets
|
||||||
|
SET pending_unfreeze_amount = GREATEST(0, pending_unfreeze_amount - $1), updated_at = $2
|
||||||
|
WHERE worker_id = $3
|
||||||
|
`,
|
||||||
|
[deductFromRow, input.now, row.worker_id],
|
||||||
|
)
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
INSERT INTO worker_wallet_ledgers (
|
||||||
|
worker_id, ledger_type, amount, balance_after, frozen_after,
|
||||||
|
related_work_order_id, note, payload_json, created_at
|
||||||
|
) VALUES ($1, 'deposit_deduction', $2, $3, $4, $5, '问题单扣减待解冻押金', $6::jsonb, $7)
|
||||||
|
`,
|
||||||
|
[
|
||||||
|
row.worker_id,
|
||||||
|
-deductFromRow,
|
||||||
|
Number(workerWallet?.available_amount || 0),
|
||||||
|
Number(workerWallet?.frozen_deposit_amount || 0),
|
||||||
|
input.workOrderId,
|
||||||
|
JSON.stringify({
|
||||||
|
workOrderId: input.workOrderId,
|
||||||
|
unfreezeId: row.id,
|
||||||
|
note: input.note,
|
||||||
|
}),
|
||||||
|
input.now,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
deductedAmount += deductFromRow
|
||||||
|
remainingToDeduct -= deductFromRow
|
||||||
|
}
|
||||||
|
|
||||||
|
return { deductedAmount, failureReason: null }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function releaseDepositUnfreeze({
|
||||||
|
unfreezeId,
|
||||||
|
now,
|
||||||
|
}: {
|
||||||
|
unfreezeId: number
|
||||||
|
now: string
|
||||||
|
}): Promise<WorkerDepositUnfreezeRow | null> {
|
||||||
|
return withTransaction(async (client) => {
|
||||||
|
const currentResult = await client.query<WorkerDepositUnfreezeRow>(
|
||||||
|
`
|
||||||
|
SELECT *
|
||||||
|
FROM worker_deposit_unfreezes
|
||||||
|
WHERE id = $1 AND status = 'pending'
|
||||||
|
FOR UPDATE
|
||||||
|
`,
|
||||||
|
[unfreezeId],
|
||||||
|
)
|
||||||
|
const unfreeze = currentResult.rows[0] || null
|
||||||
|
if (!unfreeze) return null
|
||||||
|
|
||||||
|
await ensureWorkerWalletWithClient(client, unfreeze.worker_id, now)
|
||||||
|
const wallet = await getWorkerWalletWithClient(client, unfreeze.worker_id)
|
||||||
|
const amount = Math.min(
|
||||||
|
Number(unfreeze.amount || 0),
|
||||||
|
Number(wallet?.pending_unfreeze_amount || 0),
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
UPDATE worker_deposit_unfreezes
|
||||||
|
SET status = 'released', released_at = $1, updated_at = $1
|
||||||
|
WHERE id = $2
|
||||||
|
`,
|
||||||
|
[now, unfreeze.id],
|
||||||
|
)
|
||||||
|
|
||||||
|
if (amount > 0) {
|
||||||
|
const nextAvailable = Number(wallet?.available_amount || 0) + amount
|
||||||
|
const nextPending = Math.max(0, Number(wallet?.pending_unfreeze_amount || 0) - amount)
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
UPDATE worker_wallets
|
||||||
|
SET available_amount = $1, pending_unfreeze_amount = $2, updated_at = $3
|
||||||
|
WHERE worker_id = $4
|
||||||
|
`,
|
||||||
|
[nextAvailable, nextPending, now, unfreeze.worker_id],
|
||||||
|
)
|
||||||
|
await client.query(
|
||||||
|
`
|
||||||
|
INSERT INTO worker_wallet_ledgers (
|
||||||
|
worker_id, ledger_type, amount, balance_after, frozen_after,
|
||||||
|
related_work_order_id, note, payload_json, created_at
|
||||||
|
) VALUES ($1, 'deposit_unfreeze', $2, $3, $4, $5, '押金已解冻到账', $6::jsonb, $7)
|
||||||
|
`,
|
||||||
|
[
|
||||||
|
unfreeze.worker_id,
|
||||||
|
amount,
|
||||||
|
nextAvailable,
|
||||||
|
Number(wallet?.frozen_deposit_amount || 0),
|
||||||
|
unfreeze.work_order_id,
|
||||||
|
JSON.stringify({ unfreezeId: unfreeze.id }),
|
||||||
|
now,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...unfreeze,
|
||||||
|
status: 'released',
|
||||||
|
released_at: now,
|
||||||
|
updated_at: now,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -35,10 +35,21 @@ import type {
|
|||||||
} from './types.js'
|
} from './types.js'
|
||||||
import type { PoolClient } from 'pg'
|
import type { PoolClient } from 'pg'
|
||||||
import { maybeUpgradeWorkerLevelWithClient } from './worker-ranking-repo.js'
|
import { maybeUpgradeWorkerLevelWithClient } from './worker-ranking-repo.js'
|
||||||
|
import {
|
||||||
|
enqueueDepositUnfreezeWithClient,
|
||||||
|
getOutstandingDepositAmountWithClient,
|
||||||
|
resolveOutstandingDepositAmount,
|
||||||
|
} from './work-order-deposit-repo.js'
|
||||||
|
|
||||||
export * from './work-order-query-repo.js'
|
export * from './work-order-query-repo.js'
|
||||||
export { sumPendingUnfreezeByOrderIds } from './work-order-deposit-query-repo.js'
|
export { sumPendingUnfreezeByOrderIds } from './work-order-deposit-query-repo.js'
|
||||||
export { listDueDepositUnfreezes } from './work-order-deposit-query-repo.js'
|
export { listDueDepositUnfreezes } from './work-order-deposit-query-repo.js'
|
||||||
|
export {
|
||||||
|
deductPendingDepositUnfreeze,
|
||||||
|
getOutstandingDepositAmountWithClient,
|
||||||
|
releaseDepositUnfreeze,
|
||||||
|
resolveOutstandingDepositAmount,
|
||||||
|
} from './work-order-deposit-repo.js'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createWorkOrder,
|
createWorkOrder,
|
||||||
@@ -1674,240 +1685,3 @@ export async function settleOverdueWorkOrder(input: {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deductPendingDepositUnfreeze(input: {
|
|
||||||
workOrderId: number
|
|
||||||
amount: number
|
|
||||||
note: string
|
|
||||||
now: string
|
|
||||||
}): Promise<{
|
|
||||||
deductedAmount: number
|
|
||||||
failureReason: 'no_pending_deposit' | 'amount_exceeds_pending' | null
|
|
||||||
}> {
|
|
||||||
return withTransaction(async (client) => {
|
|
||||||
const pendingResult = await client.query<WorkerDepositUnfreezeRow>(
|
|
||||||
`
|
|
||||||
SELECT *
|
|
||||||
FROM worker_deposit_unfreezes
|
|
||||||
WHERE work_order_id = $1 AND status = 'pending'
|
|
||||||
ORDER BY unfreeze_at ASC
|
|
||||||
FOR UPDATE
|
|
||||||
`,
|
|
||||||
[input.workOrderId],
|
|
||||||
)
|
|
||||||
const pending = pendingResult.rows
|
|
||||||
if (pending.length === 0) {
|
|
||||||
return { deductedAmount: 0, failureReason: 'no_pending_deposit' }
|
|
||||||
}
|
|
||||||
const totalPending = pending.reduce((sum, row) => sum + Number(row.amount || 0), 0)
|
|
||||||
if (input.amount <= 0 || input.amount > totalPending) {
|
|
||||||
return { deductedAmount: 0, failureReason: 'amount_exceeds_pending' }
|
|
||||||
}
|
|
||||||
|
|
||||||
let remainingToDeduct = input.amount
|
|
||||||
let deductedAmount = 0
|
|
||||||
|
|
||||||
for (const row of pending) {
|
|
||||||
if (remainingToDeduct <= 0) break
|
|
||||||
const rowAmount = Number(row.amount || 0)
|
|
||||||
if (rowAmount <= 0) continue
|
|
||||||
const deductFromRow = Math.min(rowAmount, remainingToDeduct)
|
|
||||||
const isFullyDeducted = deductFromRow >= rowAmount
|
|
||||||
|
|
||||||
if (isFullyDeducted) {
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
UPDATE worker_deposit_unfreezes
|
|
||||||
SET status = 'deducted', updated_at = $1
|
|
||||||
WHERE id = $2
|
|
||||||
`,
|
|
||||||
[input.now, row.id],
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
UPDATE worker_deposit_unfreezes
|
|
||||||
SET amount = amount - $1, updated_at = $2
|
|
||||||
WHERE id = $3
|
|
||||||
`,
|
|
||||||
[deductFromRow, input.now, row.id],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const workerWallet = await getWorkerWalletWithClient(client, row.worker_id)
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
UPDATE worker_wallets
|
|
||||||
SET pending_unfreeze_amount = GREATEST(0, pending_unfreeze_amount - $1), updated_at = $2
|
|
||||||
WHERE worker_id = $3
|
|
||||||
`,
|
|
||||||
[deductFromRow, input.now, row.worker_id],
|
|
||||||
)
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO worker_wallet_ledgers (
|
|
||||||
worker_id, ledger_type, amount, balance_after, frozen_after,
|
|
||||||
related_work_order_id, note, payload_json, created_at
|
|
||||||
) VALUES ($1, 'deposit_deduction', $2, $3, $4, $5, '问题单扣减待解冻押金', $6::jsonb, $7)
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
row.worker_id,
|
|
||||||
-deductFromRow,
|
|
||||||
Number(workerWallet?.available_amount || 0),
|
|
||||||
Number(workerWallet?.frozen_deposit_amount || 0),
|
|
||||||
input.workOrderId,
|
|
||||||
JSON.stringify({
|
|
||||||
workOrderId: input.workOrderId,
|
|
||||||
unfreezeId: row.id,
|
|
||||||
note: input.note,
|
|
||||||
}),
|
|
||||||
input.now,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
deductedAmount += deductFromRow
|
|
||||||
remainingToDeduct -= deductFromRow
|
|
||||||
}
|
|
||||||
|
|
||||||
return { deductedAmount, failureReason: null }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function releaseDepositUnfreeze({
|
|
||||||
unfreezeId,
|
|
||||||
now,
|
|
||||||
}: {
|
|
||||||
unfreezeId: number
|
|
||||||
now: string
|
|
||||||
}): Promise<WorkerDepositUnfreezeRow | null> {
|
|
||||||
return withTransaction(async (client) => {
|
|
||||||
const currentResult = await client.query<WorkerDepositUnfreezeRow>(
|
|
||||||
`
|
|
||||||
SELECT *
|
|
||||||
FROM worker_deposit_unfreezes
|
|
||||||
WHERE id = $1 AND status = 'pending'
|
|
||||||
FOR UPDATE
|
|
||||||
`,
|
|
||||||
[unfreezeId],
|
|
||||||
)
|
|
||||||
const unfreeze = currentResult.rows[0] || null
|
|
||||||
if (!unfreeze) return null
|
|
||||||
|
|
||||||
await ensureWorkerWalletWithClient(client, unfreeze.worker_id, now)
|
|
||||||
const wallet = await getWorkerWalletWithClient(client, unfreeze.worker_id)
|
|
||||||
const amount = Math.min(
|
|
||||||
Number(unfreeze.amount || 0),
|
|
||||||
Number(wallet?.pending_unfreeze_amount || 0),
|
|
||||||
)
|
|
||||||
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
UPDATE worker_deposit_unfreezes
|
|
||||||
SET status = 'released', released_at = $1, updated_at = $1
|
|
||||||
WHERE id = $2
|
|
||||||
`,
|
|
||||||
[now, unfreeze.id],
|
|
||||||
)
|
|
||||||
|
|
||||||
if (amount > 0) {
|
|
||||||
const nextAvailable = Number(wallet?.available_amount || 0) + amount
|
|
||||||
const nextPending = Math.max(0, Number(wallet?.pending_unfreeze_amount || 0) - amount)
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
UPDATE worker_wallets
|
|
||||||
SET available_amount = $1, pending_unfreeze_amount = $2, updated_at = $3
|
|
||||||
WHERE worker_id = $4
|
|
||||||
`,
|
|
||||||
[nextAvailable, nextPending, now, unfreeze.worker_id],
|
|
||||||
)
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO worker_wallet_ledgers (
|
|
||||||
worker_id, ledger_type, amount, balance_after, frozen_after,
|
|
||||||
related_work_order_id, note, payload_json, created_at
|
|
||||||
) VALUES ($1, 'deposit_unfreeze', $2, $3, $4, $5, '押金已解冻到账', $6::jsonb, $7)
|
|
||||||
`,
|
|
||||||
[
|
|
||||||
unfreeze.worker_id,
|
|
||||||
amount,
|
|
||||||
nextAvailable,
|
|
||||||
Number(wallet?.frozen_deposit_amount || 0),
|
|
||||||
unfreeze.work_order_id,
|
|
||||||
JSON.stringify({ unfreezeId: unfreeze.id }),
|
|
||||||
now,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...unfreeze,
|
|
||||||
status: 'released',
|
|
||||||
released_at: now,
|
|
||||||
updated_at: now,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function enqueueDepositUnfreezeWithClient(
|
|
||||||
client: PoolClient,
|
|
||||||
input: {
|
|
||||||
workerId: number
|
|
||||||
workOrderId: number
|
|
||||||
amount: number
|
|
||||||
unfreezeDays: number
|
|
||||||
now: string
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
if (input.amount <= 0) return
|
|
||||||
const unfreezeAt = new Date(
|
|
||||||
new Date(input.now).getTime() + input.unfreezeDays * 86_400_000,
|
|
||||||
).toISOString()
|
|
||||||
await client.query(
|
|
||||||
`
|
|
||||||
INSERT INTO worker_deposit_unfreezes (
|
|
||||||
worker_id, work_order_id, amount, unfreeze_at, status, created_at, updated_at
|
|
||||||
) VALUES ($1, $2, $3, $4, 'pending', $5, $5)
|
|
||||||
`,
|
|
||||||
[input.workerId, input.workOrderId, input.amount, unfreezeAt, input.now],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resolveOutstandingDepositAmount(
|
|
||||||
totals:
|
|
||||||
| {
|
|
||||||
frozen_amount?: number
|
|
||||||
released_amount?: number
|
|
||||||
deducted_amount?: number
|
|
||||||
}
|
|
||||||
| null
|
|
||||||
| undefined,
|
|
||||||
) {
|
|
||||||
return Math.max(
|
|
||||||
0,
|
|
||||||
Number(totals?.frozen_amount || 0) -
|
|
||||||
Number(totals?.released_amount || 0) -
|
|
||||||
Number(totals?.deducted_amount || 0),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getOutstandingDepositAmountWithClient(
|
|
||||||
client: PoolClient,
|
|
||||||
workerId: number,
|
|
||||||
workOrderId: number,
|
|
||||||
) {
|
|
||||||
const result = await client.query<{
|
|
||||||
frozen_amount: number
|
|
||||||
released_amount: number
|
|
||||||
deducted_amount: number
|
|
||||||
}>(
|
|
||||||
`
|
|
||||||
SELECT
|
|
||||||
COALESCE(SUM(CASE WHEN ledger_type = 'deposit_freeze' THEN ABS(amount) ELSE 0 END), 0)::int AS frozen_amount,
|
|
||||||
COALESCE(SUM(CASE WHEN ledger_type = 'deposit_release' THEN ABS(amount) ELSE 0 END), 0)::int AS released_amount,
|
|
||||||
COALESCE(SUM(CASE WHEN ledger_type = 'deposit_deduction' THEN ABS(amount) ELSE 0 END), 0)::int AS deducted_amount
|
|
||||||
FROM worker_wallet_ledgers
|
|
||||||
WHERE worker_id = $1
|
|
||||||
AND related_work_order_id = $2
|
|
||||||
`,
|
|
||||||
[workerId, workOrderId],
|
|
||||||
)
|
|
||||||
return resolveOutstandingDepositAmount(result.rows[0])
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user