import { CreateTriggerInTxn, Trigger } from 'oak-domain/lib/types/Trigger'; import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid'; import { EntityDict } from '../oak-app-domain'; import { BRC } from '../types/RuntimeCxt'; import assert from 'assert'; const triggers: Trigger[] = [ { name: '当settlePlan创建时更新关联order的settlePlanned', entity: 'settlePlan', action: 'create', when: 'before', asRoot: true, priority: 99, fn: async ({ operation }, context, option) => { const { data } = operation; let count = 0; const updateOrderFn = async (settlePlan: EntityDict['settlePlan']['CreateOperationData']) => { const [order] = await context.select('order', { data: { id: 1, paid: 1, refunded: 1, settlePlanned: 1, }, filter: { id: settlePlan.orderId, } }, { forUpdate: true }); const { id, paid, refunded, settlePlanned } = order; const newSettlePlanned = settlePlan.price! + settlePlanned!; await context.operate('order', { id: await generateNewIdAsync(), action: 'update', data: { settlePlanned: newSettlePlanned, }, filter: { id, } }, option); } if (data instanceof Array) { for (const d of data) { await updateOrderFn(d); count++; } } else { await updateOrderFn(data); count++; } return count; }, } as CreateTriggerInTxn, { name: '当settlePlan执行settle时将关联的settlement执行settle,并更新order的settled', entity: 'settlePlan', action: 'settle', when: 'before', asRoot: true, priority: 99, fn: async ({ operation }, context, option) => { const { filter } = operation; const settlePlans = await context.select('settlePlan', { data: { id: 1, price: 1, settlement$plan: { $entity: 'settlement', data: { id: 1, price: 1, accountId: 1, iState: 1, }, filter: { iState: 'unsettled', } }, orderId: 1, order: { id: 1, paid: 1, refunded: 1, settled: 1, } }, filter, }, { forUpdate: true }); const now = Date.now(); for (const settlePlan of settlePlans) { const { id, price: planPrice, settlement$plan: settlements, orderId, order } = settlePlan; assert(settlements && settlements.length > 0); //关联的settlement均执行settle并生成accountOper for (const settlement of settlements) { const { id: settlementId, price: settlementPrice, accountId, } = settlement; await context.operate('settlement', { id: await generateNewIdAsync(), action: 'settle', data: { settledAt: now, accountOper$entity: [{ id: await generateNewIdAsync(), action: 'create', data: { id: await generateNewIdAsync(), totalPlus: settlementPrice, availPlus: settlementPrice, accountId: accountId, type: 'settle', } }] }, filter: { id: settlementId, } }, option); } //更新order的settled const newSettledPrice = order?.settled! + planPrice!; await context.operate('order', { id: await generateNewIdAsync(), action: 'update', data: { settled: newSettledPrice, }, filter: { id: orderId, } }, option); } return settlePlans.length; }, }, { name: '当settlePlan执行close时将关联的settlement执行close,并更新order的settlePlanned', entity: 'settlePlan', action: 'close', when: 'before', asRoot: true, priority: 99, fn: async ({ operation }, context, option) => { const { filter } = operation; const settlePlans = await context.select('settlePlan', { data: { id: 1, price: 1, settlement$plan: { $entity: 'settlement', data: { id: 1, price: 1, accountId: 1, iState: 1, }, filter: { iState: 'unsettled', } }, orderId: 1, order: { id: 1, settlePlanned: 1, } }, filter, }, { forUpdate: true }); const now = Date.now(); for (const settlePlan of settlePlans) { const { id, price: planPrice, settlement$plan: settlements, orderId, order } = settlePlan || {}; assert(settlements && settlements.length > 0); //关联的settlement均执行close for (const settlement of settlements) { const { id: settlementId, } = settlement; await context.operate('settlement', { id: await generateNewIdAsync(), action: 'close', data: { closedAt: now, }, filter: { id: settlementId, } }, option); } //更新order的settlePlanned const newSettlePlanned = order?.settlePlanned! - planPrice!; await context.operate('order', { id: await generateNewIdAsync(), action: 'update', data: { settlePlanned: newSettlePlanned, }, filter: { id: orderId, } }, option); } return settlePlans.length; }, }, ]; export default triggers;