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  }