github.com/decred/politeia@v1.4.0/politeiawww/legacy/cmsnotifications.go (about) 1 // Copyright (c) 2019 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package legacy 6 7 import ( 8 "time" 9 10 cms "github.com/decred/politeia/politeiawww/api/cms/v1" 11 "github.com/decred/politeia/politeiawww/legacy/user" 12 ) 13 14 const ( 15 // Seconds Minutes Hours Days Months DayOfWeek 16 firstEmailSchedule = "0 0 12 1 * *" // Check at 12:00 PM on 1st day every month 17 secondEmailSchedule = "0 0 12 4 * *" // Check at 12:00 PM on 4th day every month 18 thirdEmailSchedule = "0 0 12 7 * *" // Check at 12:00 PM on 7th day every month 19 20 firstEmailCheck = 1 21 secondEmailCheck = 2 22 thirdEmailCheck = 3 23 ) 24 25 func (p *Politeiawww) checkInvoiceNotifications() { 26 log.Infof("Starting cron for invoice email checking") 27 // Launch invoice notification cron job 28 err := p.cron.AddFunc(firstEmailSchedule, func() { 29 log.Infof("Running first invoice email notification cron") 30 p.invoiceNotification(firstEmailCheck) 31 }) 32 if err != nil { 33 log.Errorf("Error running first invoice notification cron: %v", err) 34 } 35 err = p.cron.AddFunc(secondEmailSchedule, func() { 36 log.Infof("Running second invoice email notification cron") 37 p.invoiceNotification(secondEmailCheck) 38 }) 39 if err != nil { 40 log.Errorf("Error running second invoice notification cron: %v", err) 41 } 42 err = p.cron.AddFunc(thirdEmailSchedule, func() { 43 log.Infof("Running third invoice email notification cron") 44 p.invoiceNotification(thirdEmailCheck) 45 }) 46 if err != nil { 47 log.Errorf("Error running third invoice notification cron: %v", err) 48 } 49 } 50 51 func (p *Politeiawww) invoiceNotification(emailCheckVersion int) { 52 currentMonth := time.Now().Month() 53 currentYear := time.Now().Year() 54 // Check all CMS users 55 err := p.db.AllUsers(func(user *user.User) { 56 log.Tracef("Checking user: %v", user.Username) 57 if user.Admin { 58 return 59 } 60 61 cmsUser, err := p.getCMSUserByID(user.ID.String()) 62 if err != nil { 63 log.Errorf("Error retrieving user invoices email: %v %v", err, 64 user.Email) 65 return 66 } 67 68 // Skip if user isn't a direct or supervisor contractor. 69 if cmsUser.ContractorType != cms.ContractorTypeDirect && 70 cmsUser.ContractorType != cms.ContractorTypeSupervisor { 71 return 72 } 73 74 // If HashedPassword not set to anything that means the user has 75 // not completed registration. 76 if len(user.HashedPassword) == 0 { 77 return 78 } 79 invoiceFound := false 80 userInvoices, err := p.cmsDB.InvoicesByUserID(user.ID.String()) 81 if err != nil { 82 log.Errorf("Error retrieving user invoices email: %v %v", err, 83 user.Email) 84 return 85 } 86 for _, inv := range userInvoices { 87 // Check to see if invoices match last month + current year OR 88 // if it's currently January and the user has not submitted an 89 // invoice for December of the previous year. 90 if (inv.Month == uint(currentMonth-1) && 91 inv.Year == uint(currentYear)) || 92 (currentMonth == 1 && inv.Month == 12 && 93 inv.Year == uint(currentYear-1)) { 94 invoiceFound = true 95 break 96 } 97 } 98 log.Tracef("Checked user: %v sending email? %v", user.Username, 99 !invoiceFound) 100 if !invoiceFound { 101 switch emailCheckVersion { 102 case firstEmailCheck: 103 err = p.emailInvoiceNotifications(user.Email, user.Username, 104 "Monthly Invoice Reminder", 105 invoiceFirstNotificationTmpl) 106 if err != nil { 107 log.Errorf("Error sending first email: %v %v", err, user.Email) 108 } 109 case secondEmailCheck: 110 err = p.emailInvoiceNotifications(user.Email, user.Username, 111 "Awaiting Monthly Invoice", 112 invoiceSecondNotificationTmpl) 113 if err != nil { 114 log.Errorf("Error sending second email: %v %v", err, user.Email) 115 } 116 117 case thirdEmailCheck: 118 err = p.emailInvoiceNotifications(user.Email, user.Username, 119 "Final Invoice Notice", 120 invoiceFinalNotificationTmpl) 121 if err != nil { 122 log.Errorf("Error sending second email: %v %v", err, user.Email) 123 } 124 } 125 } 126 }) 127 if err != nil { 128 log.Errorf("Error querying for AllUsers: %v", err) 129 } 130 }