@@ -353,7 +353,7 @@ export class AdminService {
353353
354354 /**
355355 * Finds challenge billing-account rows that need to be recalculated after a
356- * wallet-admin payment status change.
356+ * wallet-admin payment status or amount change.
357357 *
358358 * @param payments payment rows selected by the update request.
359359 * @returns unique challenge and billing-account pairs touched by USD
@@ -402,7 +402,7 @@ export class AdminService {
402402
403403 /**
404404 * Finds engagement billing-account rows that need to be reconciled after a
405- * wallet-admin payment status change.
405+ * wallet-admin payment status or amount change.
406406 *
407407 * @param payments payment rows selected by the update request.
408408 * @returns unique engagement assignment and billing-account pairs touched by
@@ -539,6 +539,39 @@ export class AdminService {
539539 ) ;
540540 }
541541
542+ /**
543+ * Recomputes the persisted engagement billing fee after an admin amount edit.
544+ *
545+ * Engagement consumed rows store payment total plus `payment.challenge_fee`.
546+ * When wallet admin adjusts the payment total, the fee must be recalculated
547+ * from the persisted markup before finance resyncs the BA consumed row.
548+ *
549+ * @param category winning category for the payment being edited.
550+ * @param challengeMarkup markup persisted on the payment row.
551+ * @param totalAmount new payment total amount.
552+ * @returns recalculated fee for engagement payments, or `undefined` when the
553+ * payment is not an engagement payment or has no valid persisted markup.
554+ * @throws This helper does not throw.
555+ */
556+ private calculateAdjustedChallengeFee (
557+ category : winnings_category | null ,
558+ challengeMarkup : Prisma . Decimal | number | string | null ,
559+ totalAmount : number ,
560+ ) : number | undefined {
561+ if ( category !== winnings_category . ENGAGEMENT_PAYMENT ) {
562+ return undefined ;
563+ }
564+
565+ const markup = Number ( challengeMarkup ) ;
566+ if ( ! Number . isFinite ( markup ) || markup < 0 ) {
567+ return undefined ;
568+ }
569+
570+ return this . toPaymentAmount (
571+ new Prisma . Decimal ( totalAmount ) . mul ( new Prisma . Decimal ( markup ) ) ,
572+ ) ;
573+ }
574+
542575 /**
543576 * Sums non-cancelled USD payment rows for a challenge and billing account.
544577 *
@@ -574,8 +607,8 @@ export class AdminService {
574607 }
575608
576609 /**
577- * Rewrites challenge billing-account budget rows after a wallet-admin status
578- * update changes the active payment total.
610+ * Rewrites challenge billing-account budget rows after a wallet-admin update
611+ * changes the active payment total.
579612 *
580613 * @param targets unique challenge and billing-account pairs to synchronize.
581614 * @returns promise resolved after every target has been sent to BA.
@@ -663,7 +696,7 @@ export class AdminService {
663696
664697 /**
665698 * Reconciles engagement billing-account consumed rows after a wallet-admin
666- * cancellation changes the active payment set.
699+ * update changes the active payment amounts or active payment set.
667700 *
668701 * @param targets unique engagement assignment and billing-account pairs to
669702 * synchronize.
@@ -780,14 +813,15 @@ export class AdminService {
780813 tx : Prisma . TransactionClient ,
781814 ) => Promise < unknown > ) [ ] = [ ] ;
782815 const now = new Date ( ) . getTime ( ) ;
783- const challengeBudgetSyncTargets =
784- body . paymentStatus === PaymentStatus . CANCELLED
785- ? this . getChallengeBudgetSyncTargets ( payments )
786- : [ ] ;
787- const engagementBudgetSyncTargets =
788- body . paymentStatus === PaymentStatus . CANCELLED
789- ? this . getEngagementBudgetSyncTargets ( payments )
790- : [ ] ;
816+ const shouldSyncBudget =
817+ body . paymentStatus === PaymentStatus . CANCELLED ||
818+ body . paymentAmount !== undefined ;
819+ const challengeBudgetSyncTargets = shouldSyncBudget
820+ ? this . getChallengeBudgetSyncTargets ( payments )
821+ : [ ] ;
822+ const engagementBudgetSyncTargets = shouldSyncBudget
823+ ? this . getEngagementBudgetSyncTargets ( payments )
824+ : [ ] ;
791825
792826 // iterate payments and build transaction list
793827 payments . forEach ( ( payment ) => {
@@ -999,6 +1033,12 @@ export class AdminService {
9991033 ) {
10001034 // ideally we should be maintaining the original split of the payment amount between installments - but we aren't really using splits anymore
10011035 if ( payment . installment_number === 1 ) {
1036+ const challengeFee = this . calculateAdjustedChallengeFee (
1037+ payment . winnings . category ,
1038+ payment . challenge_markup ,
1039+ body . paymentAmount ,
1040+ ) ;
1041+
10021042 transactions . push ( ( tx ) =>
10031043 this . updatePaymentAmount (
10041044 userId ,
@@ -1007,6 +1047,7 @@ export class AdminService {
10071047 body . paymentAmount ,
10081048 body . paymentAmount ,
10091049 body . paymentAmount ,
1050+ challengeFee ,
10101051 version ,
10111052 tx ,
10121053 ) ,
@@ -1027,6 +1068,12 @@ export class AdminService {
10271068 `update amounts -> ${ body . paymentAmount . toFixed ( 2 ) } (installment 1)` ,
10281069 ) ;
10291070 } else {
1071+ const challengeFee = this . calculateAdjustedChallengeFee (
1072+ payment . winnings . category ,
1073+ payment . challenge_markup ,
1074+ body . paymentAmount ,
1075+ ) ;
1076+
10301077 transactions . push ( ( tx ) =>
10311078 this . updatePaymentAmount (
10321079 userId ,
@@ -1035,6 +1082,7 @@ export class AdminService {
10351082 0 ,
10361083 0 ,
10371084 body . paymentAmount ,
1085+ challengeFee ,
10381086 version ,
10391087 tx ,
10401088 ) ,
@@ -1436,6 +1484,7 @@ export class AdminService {
14361484 netAmount : number ,
14371485 grossAmount : number ,
14381486 totalAmount : number ,
1487+ challengeFee : number | undefined ,
14391488 currentVersion : number ,
14401489 tx ?: Prisma . TransactionClient ,
14411490 ) {
@@ -1459,6 +1508,7 @@ export class AdminService {
14591508 net_amount : netAmount ,
14601509 gross_amount : grossAmount ,
14611510 total_amount : totalAmount ,
1511+ challenge_fee : challengeFee ,
14621512 updated_at : new Date ( ) ,
14631513 updated_by : userId ,
14641514 version : currentVersion + 1 ,
0 commit comments