55 "encoding/json"
66 "flag"
77 "fmt"
8+ "io"
89 "log"
910 "os"
1011 "os/user"
@@ -46,6 +47,7 @@ var start = flag.Int("period_start", 0, "start of report period")
4647var end = flag .Int ("period_end" , 0 , "end of report period" )
4748var period = flag .String ("period" , "" , "Predefined period: last_month, last_quarter" )
4849var report_type = flag .String ("query_type" , "stripe_vat" , "Type of query: stripe_vat, paypal_vat, referral_transactions" )
50+ var email_to = flag .String ("email" , "" , "Email address to send the report to as a text attachment" )
4951
5052func send_email_no_tracking_no_hubspot (email_from string , email_target string , subject string , text string , html string , attachment_file string ) error {
5153 from := mail .NewEmail ("FastNetMon Team" , email_from )
@@ -89,7 +91,7 @@ func send_email_no_tracking_no_hubspot(email_from string, email_target string, s
8991 return nil
9092}
9193
92- func calculatePayPalVAT () error {
94+ func calculatePayPalVAT (output io. Writer ) error {
9395 transactions , err := get_all_paypal_transactions_period ("" , int64 (* start ), int64 (* end ))
9496
9597 if err != nil {
@@ -116,7 +118,7 @@ func calculatePayPalVAT() error {
116118 vat_info = fmt .Sprintf ("VAT: %s Rate: 20%%" , customer .VatNumber )
117119 }
118120
119- fmt .Printf ( "Date %s Amount: %.2f %s, Company: %s Country: %s %v\n " ,
121+ fmt .Fprintf ( output , "Date %s Amount: %.2f %s, Company: %s Country: %s %v\n " ,
120122 txnDate .Format (time .RFC3339 ),
121123 float64 (txn .Amount )/ 100 ,
122124 txn .CurrencyCode ,
@@ -129,7 +131,7 @@ func calculatePayPalVAT() error {
129131 return nil
130132}
131133
132- func getReferralTransactions () error {
134+ func getReferralTransactions (output io. Writer ) error {
133135 transactions , err := get_all_transactions_period ("" , int64 (* start ), int64 (* end ))
134136
135137 if err != nil {
@@ -166,7 +168,7 @@ func getReferralTransactions() error {
166168 continue
167169 }
168170
169- fmt .Printf ( "%s Amount: %.2f %s Company: %s Subscription ID: %s Referrer: %v\n " ,
171+ fmt .Fprintf ( output , "%s Amount: %.2f %s Company: %s Subscription ID: %s Referrer: %v\n " ,
170172 txnDate .Format (time .RFC3339 ),
171173 float64 (txn .Amount )/ 100 ,
172174 txn .CurrencyCode ,
@@ -178,12 +180,12 @@ func getReferralTransactions() error {
178180 total_value += float64 (txn .Amount ) / 100
179181 }
180182
181- log . Printf ( "Total value: %2.f" , total_value )
183+ fmt . Fprintf ( output , "Total value: %2.f" , total_value )
182184
183185 return nil
184186}
185187
186- func calculateStripeVAT () error {
188+ func calculateStripeVAT (output io. Writer ) error {
187189
188190 i := payout .List (& stripe.PayoutListParams {ArrivalDateRange : & stripe.RangeQueryParams {
189191 GreaterThanOrEqual : int64 (* start ),
@@ -218,7 +220,7 @@ func calculateStripeVAT() error {
218220 payment_result = fmt .Sprintf ("Failed due to reason: %s" , payout .FailureCode )
219221 }
220222
221- fmt .Printf ( "Date Arrived: %v Amount: %s %s %s\n " , dateArrived , PrintAmount (payout .Amount ), payout .Currency , payment_result )
223+ fmt .Fprintf ( output , "Date Arrived: %v Amount: %s %s %s\n " , dateArrived , PrintAmount (payout .Amount ), payout .Currency , payment_result )
222224
223225 // Get sub transactions for this payout
224226 transactions , err := GetPayoutTransactions (payout .ID )
@@ -234,20 +236,20 @@ func calculateStripeVAT() error {
234236
235237 if chargebeeUser == "" {
236238 if txn .Description == "REFUND FOR PAYOUT (STRIPE PAYOUT)" {
237- fmt .Printf ( "Net amount: %v It's probably refund transaction retry from previously failed refunds\n " , PrintAmount (txn .Net ))
239+ fmt .Fprintf ( output , "Net amount: %v It's probably refund transaction retry from previously failed refunds\n " , PrintAmount (txn .Net ))
238240 continue
239241 } else if txn .Type == "refund_failure" {
240- fmt .Printf ( "Net amount: %v It's probably refund transaction\n " , PrintAmount (txn .Net ))
242+ fmt .Fprintf ( output , "Net amount: %v It's probably refund transaction\n " , PrintAmount (txn .Net ))
241243 continue
242244 } else if txn .Type == "stripe_fee" {
243- fmt .Printf ( "Net amount: %v Radar for Fraud teams fee, it's Stripe fee for fraud screening\n " , PrintAmount (txn .Net ))
245+ fmt .Fprintf ( output , "Net amount: %v Radar for Fraud teams fee, it's Stripe fee for fraud screening\n " , PrintAmount (txn .Net ))
244246 continue
245247 } else if txn .Type == "adjustment" && txn .ReportingCategory == "dispute" {
246248 // &{Amount:-206192 AvailableOn:1717696135 Created:1717696135 Currency:gbp
247249 // Description:Chargeback withdrawal for ch_xxx ExchangeRate:0 ID:txn_xxx
248250 // Fee:2000 FeeDetails:[0x14000d46050] Net:-208192 Recipient: ReportingCategory:dispute
249251 // Source:0x14000531570 Status:available Type:adjustment}
250- fmt .Printf ( "Net amount: %v It's probably chargeback transaction\n " , PrintAmount (txn .Net ))
252+ fmt .Fprintf ( output , "Net amount: %v It's probably chargeback transaction\n " , PrintAmount (txn .Net ))
251253 continue
252254 } else if txn .Type == "adjustment" && txn .Description == "Contribution from reserved balance" && txn .Amount == 0 && txn .Fee == 0 {
253255 // I suppose it's some kind of Stripe internal transaction which has no meaning for accounting purposes
@@ -256,10 +258,10 @@ func calculateStripeVAT() error {
256258 // I suppose it's some kind of Stripe internal transaction which has no meaning for accounting purposes
257259 continue
258260 } else if txn .Type == "payout_minimum_balance_hold" && txn .ReportingCategory == "payout_minimum_balance_hold" {
259- fmt .Printf ( "Stripe hold part of payment to maintain balance: %v\n " , PrintAmount (txn .Net ))
261+ fmt .Fprintf ( output , "Stripe hold part of payment to maintain balance: %v\n " , PrintAmount (txn .Net ))
260262 continue
261263 } else if txn .Type == "payout_minimum_balance_release" && txn .ReportingCategory == "payout_minimum_balance_release" {
262- fmt .Printf ( "Stripe released part of payment to maintain balance: %v\n " , PrintAmount (txn .Net ))
264+ fmt .Fprintf ( output , "Stripe released part of payment to maintain balance: %v\n " , PrintAmount (txn .Net ))
263265 continue
264266 } else {
265267 return fmt .Errorf ("unexpected issue with match from description: '%s' for transaction: %+v" , txn .Description , txn )
@@ -300,10 +302,10 @@ func calculateStripeVAT() error {
300302 full_country_name = country_lookup_res .Name .BaseLang .Common
301303 }
302304
303- fmt .Printf ( "Net amount: %v %s Company: %s Country: %s %s\n " , PrintAmount (txn .Net ), txn .Currency , user .BillingAddress .Company , full_country_name , vatSection )
305+ fmt .Fprintf ( output , "Net amount: %v %s Company: %s Country: %s %s\n " , PrintAmount (txn .Net ), txn .Currency , user .BillingAddress .Company , full_country_name , vatSection )
304306 }
305307
306- fmt .Printf ( "\n " )
308+ fmt .Fprintf ( output , "\n " )
307309 }
308310
309311 return nil
@@ -380,28 +382,53 @@ func main() {
380382 Level : stripe .LevelError ,
381383 }
382384
383- if * report_type == "paypal_vat" {
384- if err := calculatePayPalVAT (); err != nil {
385- log .Fatalf ("PayPal VAT report failed: %v" , err )
386- }
385+ var output io.Writer = os .Stdout
386+ var tmpFile * os.File
387387
388- os .Exit (0 )
389- } else if * report_type == "referral_transactions" {
390- if err := getReferralTransactions (); err != nil {
391- log .Fatalf ("Referral transactions report failed: %v" , err )
388+ if * email_to != "" {
389+ var err error
390+ tmpFile , err = os .CreateTemp ("" , "report-*.txt" )
391+ if err != nil {
392+ log .Fatalf ("Cannot create temp file for report: %v" , err )
392393 }
394+ defer os .Remove (tmpFile .Name ())
395+ defer tmpFile .Close ()
396+ output = tmpFile
397+ }
393398
394- os .Exit (0 )
395- } else if * report_type == "stripe_vat" {
396- if err := calculateStripeVAT (); err != nil {
397- log .Fatalf ("Stripe VAT report failed: %v" , err )
398- }
399+ var reportErr error
399400
400- os .Exit (0 )
401+ if * report_type == "paypal_vat" {
402+ reportErr = calculatePayPalVAT (output )
403+ } else if * report_type == "referral_transactions" {
404+ reportErr = getReferralTransactions (output )
405+ } else if * report_type == "stripe_vat" {
406+ reportErr = calculateStripeVAT (output )
401407 } else {
402408 log .Fatalf ("Unknown report type: %s" , * report_type )
403409 }
404410
411+ if reportErr != nil {
412+ log .Fatalf ("%s report failed: %v" , * report_type , reportErr )
413+ }
414+
415+ if * email_to != "" {
416+ tmpFile .Close ()
417+
418+ err := send_email_no_tracking_no_hubspot (
419+ "reports@fastnetmon.com" ,
420+ * email_to ,
421+ fmt .Sprintf ("%s report" , * report_type ),
422+ "Please find the report attached." ,
423+ "" ,
424+ tmpFile .Name ())
425+
426+ if err != nil {
427+ log .Fatalf ("Cannot send report email: %v" , err )
428+ }
429+
430+ log .Printf ("Report sent to %s" , * email_to )
431+ }
405432}
406433
407434// Returns absolute value for negative or positive values
0 commit comments