55 "errors"
66 "fmt"
77 "net/http"
8+ "os"
9+ "path/filepath"
810 "strconv"
911 "strings"
1012 "time"
@@ -119,6 +121,64 @@ func (a *App) GetInvoiceHandler(req *http.Request) (interface{}, Response) {
119121 }, Ok ()
120122}
121123
124+ // DownloadInvoiceHandler downloads user's invoice by ID
125+ // Example endpoint: Downloads user's invoice by ID
126+ // @Summary Downloads user's invoice by ID
127+ // @Description Downloads user's invoice by ID
128+ // @Tags Invoice
129+ // @Accept json
130+ // @Produce json
131+ // @Security BearerAuth
132+ // @Param id path string true "Invoice ID"
133+ // @Success 200 {object} Response
134+ // @Failure 400 {object} Response
135+ // @Failure 401 {object} Response
136+ // @Failure 404 {object} Response
137+ // @Failure 500 {object} Response
138+ // @Router /invoice/download/{id} [get]
139+ func (a * App ) DownloadInvoiceHandler (req * http.Request ) (interface {}, Response ) {
140+ userID := req .Context ().Value (middlewares .UserIDKey ("UserID" )).(string )
141+
142+ id , err := strconv .Atoi (mux .Vars (req )["id" ])
143+ if err != nil {
144+ log .Error ().Err (err ).Send ()
145+ return nil , BadRequest (errors .New ("failed to read invoice id" ))
146+ }
147+
148+ invoice , err := a .db .GetInvoice (id )
149+ if err == gorm .ErrRecordNotFound {
150+ return nil , NotFound (errors .New ("invoice is not found" ))
151+ }
152+ if err != nil {
153+ log .Error ().Err (err ).Send ()
154+ return nil , InternalServerError (errors .New (internalServerErrorMsg ))
155+ }
156+
157+ if userID != invoice .UserID {
158+ return nil , NotFound (errors .New ("invoice is not found" ))
159+ }
160+
161+ // Get downloads dir
162+ homeDir , err := os .UserHomeDir ()
163+ if err != nil {
164+ log .Error ().Err (err ).Send ()
165+ return nil , InternalServerError (errors .New (internalServerErrorMsg ))
166+ }
167+
168+ downloadsDir := filepath .Join (homeDir , "Downloads" )
169+ pdfPath := filepath .Join (downloadsDir , fmt .Sprintf ("invoice-%s-%d.pdf" , invoice .UserID , invoice .ID ))
170+
171+ err = os .WriteFile (pdfPath , invoice .FileData , 0644 )
172+ if err != nil {
173+ log .Error ().Err (err ).Send ()
174+ return nil , InternalServerError (errors .New (internalServerErrorMsg ))
175+ }
176+
177+ return ResponseMsg {
178+ Message : fmt .Sprintf ("Invoice is downloaded successfully at %s" , pdfPath ),
179+ }, Ok ()
180+ }
181+
122182// PayInvoiceHandler pay user's invoice
123183// Example endpoint: Pay user's invoice
124184// @Summary Pay user's invoice
@@ -213,7 +273,7 @@ func (a *App) monthlyInvoices() {
213273 // Create invoices for all system users
214274 for _ , user := range users {
215275 // 1. Create new monthly invoice
216- if err = a .createInvoice (user . ID . String () , now ); err != nil {
276+ if err = a .createInvoice (user , now ); err != nil {
217277 log .Error ().Err (err ).Send ()
218278 }
219279
@@ -275,15 +335,15 @@ func (a *App) monthlyInvoices() {
275335 }
276336}
277337
278- func (a * App ) createInvoice (userID string , now time.Time ) error {
338+ func (a * App ) createInvoice (user models. User , now time.Time ) error {
279339 monthStart := time .Date (now .Year (), now .Month (), 0 , 0 , 0 , 0 , 0 , time .Local )
280340
281- vms , err := a .db .GetAllSuccessfulVms (userID )
341+ vms , err := a .db .GetAllSuccessfulVms (user . ID . String () )
282342 if err != nil && err != gorm .ErrRecordNotFound {
283343 return err
284344 }
285345
286- k8s , err := a .db .GetAllSuccessfulK8s (userID )
346+ k8s , err := a .db .GetAllSuccessfulK8s (user . ID . String () )
287347 if err != nil && err != gorm .ErrRecordNotFound {
288348 return err
289349 }
@@ -308,6 +368,8 @@ func (a *App) createInvoice(userID string, now time.Time) error {
308368 DeploymentResources : vm .Resources ,
309369 DeploymentType : "vm" ,
310370 DeploymentID : vm .ID ,
371+ DeploymentName : vm .Name ,
372+ DeploymentCreatedAt : vm .CreatedAt ,
311373 HasPublicIP : vm .Public ,
312374 PeriodInHours : time .Since (usageStart ).Hours (),
313375 Cost : cost ,
@@ -333,6 +395,8 @@ func (a *App) createInvoice(userID string, now time.Time) error {
333395 DeploymentResources : cluster .Master .Resources ,
334396 DeploymentType : "k8s" ,
335397 DeploymentID : cluster .ID ,
398+ DeploymentName : cluster .Master .Name ,
399+ DeploymentCreatedAt : cluster .CreatedAt ,
336400 HasPublicIP : cluster .Master .Public ,
337401 PeriodInHours : time .Since (usageStart ).Hours (),
338402 Cost : cost ,
@@ -342,11 +406,22 @@ func (a *App) createInvoice(userID string, now time.Time) error {
342406 }
343407
344408 if len (items ) > 0 {
345- if err = a . db . CreateInvoice ( & models.Invoice {
346- UserID : userID ,
409+ in := models.Invoice {
410+ UserID : user . ID . String () ,
347411 Total : total ,
348412 Deployments : items ,
349- }); err != nil {
413+ }
414+
415+ // Creating pdf for invoice
416+ pdfContent , err := internal .CreateInvoicePDF (in , user )
417+ if err != nil {
418+ return err
419+ }
420+
421+ in .FileData = pdfContent
422+
423+ // Creating invoice in db
424+ if err = a .db .CreateInvoice (& in ); err != nil {
350425 return err
351426 }
352427 }
0 commit comments