@@ -12,8 +12,8 @@ export const createSalesPayout = async ({
1212} : {
1313 programId : string ;
1414 partnerId : string ;
15- periodStart : Date ;
16- periodEnd : Date ;
15+ periodStart ? : Date | null ;
16+ periodEnd ? : Date | null ;
1717 description ?: string ;
1818} ) => {
1919 return await prisma . $transaction ( async ( tx ) => {
@@ -23,10 +23,6 @@ export const createSalesPayout = async ({
2323 partnerId,
2424 payoutId : null ,
2525 status : "pending" , // We only want to pay out sales that are pending (not refunded / fraud / duplicate)
26- createdAt : {
27- gte : periodStart ,
28- lte : periodEnd ,
29- } ,
3026 // Referral commissions are held for 30 days before becoming available.
3127 // createdAt: {
3228 // lte: subDays(new Date(), 30),
@@ -35,75 +31,100 @@ export const createSalesPayout = async ({
3531 select : {
3632 id : true ,
3733 earnings : true ,
34+ createdAt : true ,
3835 } ,
3936 } ) ;
4037
4138 if ( ! sales . length ) {
4239 return ;
4340 }
4441
45- const amount = sales . reduce ( ( total , sale ) => total + sale . earnings , 0 ) ;
4642 const quantity = sales . length ;
47- let payout : Payout | null = null ;
48-
49- // Check if the partner has another pending payout
50- payout = await tx . payout . findFirst ( {
51- where : {
52- programId,
53- partnerId,
54- status : "pending" ,
55- type : "sales" ,
56- } ,
57- } ) ;
43+ const amount = sales . reduce ( ( total , sale ) => total + sale . earnings , 0 ) ;
5844
59- // Update the existing payout
60- if ( payout ) {
61- await tx . payout . update ( {
62- where : {
63- id : payout . id ,
64- } ,
65- data : {
66- amount : {
67- increment : amount ,
68- } ,
69- quantity : {
70- increment : quantity ,
71- } ,
72- periodEnd,
73- } ,
74- } ) ;
45+ if ( ! periodStart ) {
46+ // get the earliest sale date
47+ periodStart = sales . reduce (
48+ ( min , sale ) => ( sale . createdAt < min ? sale . createdAt : min ) ,
49+ sales [ 0 ] . createdAt ,
50+ ) ;
51+ }
7552
76- console . info ( "Payout updated" , payout ) ;
53+ if ( ! periodEnd ) {
54+ // get the end of the month of the latest sale
55+ // e.g. if the latest sale is 2024-12-16, the periodEnd should be 2024-12-31
56+ const latestSale = sales . reduce (
57+ ( max , sale ) => ( sale . createdAt > max ? sale . createdAt : max ) ,
58+ sales [ 0 ] . createdAt ,
59+ ) ;
60+ periodEnd = new Date (
61+ latestSale . getFullYear ( ) ,
62+ latestSale . getMonth ( ) + 1 ,
63+ 0 ,
64+ ) ;
7765 }
7866
79- // Create the payout
80- else {
81- payout = await tx . payout . create ( {
82- data : {
83- id : createId ( { prefix : "po_" } ) ,
67+ let payout : Payout | null = null ;
68+
69+ // only create a payout if the total sale amount is greater than 0
70+ if ( amount > 0 ) {
71+ // Check if the partner has another pending payout
72+ const existingPayout = await tx . payout . findFirst ( {
73+ where : {
8474 programId,
8575 partnerId,
86- amount,
87- periodStart,
88- periodEnd,
89- quantity,
90- description,
76+ status : "pending" ,
77+ type : "sales" ,
9178 } ,
9279 } ) ;
9380
94- console . info ( "Payout created" , payout ) ;
95- }
81+ // Update the existing payout
82+ if ( existingPayout ) {
83+ payout = await tx . payout . update ( {
84+ where : {
85+ id : existingPayout . id ,
86+ } ,
87+ data : {
88+ amount : {
89+ increment : amount ,
90+ } ,
91+ quantity : {
92+ increment : quantity ,
93+ } ,
94+ periodEnd,
95+ description : existingPayout . description ?? "Dub Partners payout" ,
96+ } ,
97+ } ) ;
9698
97- if ( ! payout ) {
98- throw new Error (
99- `Failed to create payout for ${ partnerId } in ${ programId } .` ,
100- ) ;
99+ console . info ( "Payout updated" , payout ) ;
100+ }
101+
102+ // Create the payout
103+ else {
104+ payout = await tx . payout . create ( {
105+ data : {
106+ id : createId ( { prefix : "po_" } ) ,
107+ programId,
108+ partnerId,
109+ amount,
110+ periodStart,
111+ periodEnd,
112+ quantity,
113+ description : description ?? "Dub Partners payout" ,
114+ } ,
115+ } ) ;
116+
117+ console . info ( "Payout created" , payout ) ;
118+ }
101119 }
102120
103121 // Update the sales records
104122 await tx . sale . updateMany ( {
105123 where : { id : { in : sales . map ( ( sale ) => sale . id ) } } ,
106- data : { payoutId : payout . id , status : "processed" } ,
124+ data : {
125+ status : "processed" ,
126+ ...( payout ? { payoutId : payout . id } : { } ) ,
127+ } ,
107128 } ) ;
108129
109130 return payout ;
0 commit comments