From b4ab4e35fb51754478ebc378d53453cf5996ea65 Mon Sep 17 00:00:00 2001 From: Alex Yocom-Piatt Date: Wed, 12 Aug 2020 16:38:02 -0400 Subject: [PATCH] add db line item approval --- politeiawww/api/cms/v1/v1.go | 1 + .../cmsdatabase/cockroachdb/cockroachdb.go | 4 +++- .../cmsdatabase/cockroachdb/encoding.go | 3 +++ politeiawww/cmsdatabase/cockroachdb/models.go | 1 + politeiawww/cmsdatabase/database.go | 1 + politeiawww/convert.go | 19 +++++++++++++++++-- politeiawww/invoices.go | 8 +++++++- 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/politeiawww/api/cms/v1/v1.go b/politeiawww/api/cms/v1/v1.go index c73bcc56c4..fe5970c715 100644 --- a/politeiawww/api/cms/v1/v1.go +++ b/politeiawww/api/cms/v1/v1.go @@ -508,6 +508,7 @@ type LineItemsInput struct { SubRate uint `json:"subrate"` // The payrate of the subcontractor Labor uint `json:"labor"` // Number of minutes (if labor) Expenses uint `json:"expenses"` // Total cost (in USD cents) of line item (if expense or misc) + Approved bool `json:"approved"` // Proposal owner approved this line item (if proposal token specified) } // PolicyReply returns the various policy information while in CMS mode. diff --git a/politeiawww/cmsdatabase/cockroachdb/cockroachdb.go b/politeiawww/cmsdatabase/cockroachdb/cockroachdb.go index 166c5598ec..30ffda89ca 100644 --- a/politeiawww/cmsdatabase/cockroachdb/cockroachdb.go +++ b/politeiawww/cmsdatabase/cockroachdb/cockroachdb.go @@ -603,7 +603,8 @@ func (c *cockroachdb) InvoicesByLineItemsProposalToken(token string) ([]database line_items.proposal_url, line_items.labor, line_items.expenses, - line_items.contractor_rate AS sub_rate + line_items.contractor_rate AS sub_rate, + line_items.approved FROM invoices INNER JOIN line_items ON invoices.token = line_items.invoice_token @@ -648,6 +649,7 @@ type MatchingLineItems struct { PublicKey string ExchangeRate uint SubRate uint + Approved bool } // Close satisfies the database interface. diff --git a/politeiawww/cmsdatabase/cockroachdb/encoding.go b/politeiawww/cmsdatabase/cockroachdb/encoding.go index 61b300e41a..790b9c277b 100644 --- a/politeiawww/cmsdatabase/cockroachdb/encoding.go +++ b/politeiawww/cmsdatabase/cockroachdb/encoding.go @@ -112,6 +112,7 @@ func EncodeInvoiceLineItem(dbLineItem *database.LineItem) LineItem { lineItem.Expenses = dbLineItem.Expenses lineItem.ContractorRate = dbLineItem.ContractorRate lineItem.SubUserID = dbLineItem.SubUserID + lineItem.Approved = dbLineItem.Approved return lineItem } @@ -128,6 +129,7 @@ func DecodeInvoiceLineItem(lineItem *LineItem) *database.LineItem { dbLineItem.Expenses = lineItem.Expenses dbLineItem.ContractorRate = lineItem.ContractorRate dbLineItem.SubUserID = lineItem.SubUserID + dbLineItem.Approved = lineItem.Approved return dbLineItem } @@ -267,6 +269,7 @@ func convertMatchingLineItemToInvoices(matching []MatchingLineItems) []database. Expenses: vv.Expenses, ProposalURL: vv.ProposalURL, ContractorRate: vv.SubRate, + Approved: vv.Approved, } inv := database.Invoice{ PublicKey: vv.PublicKey, diff --git a/politeiawww/cmsdatabase/cockroachdb/models.go b/politeiawww/cmsdatabase/cockroachdb/models.go index 87d7cbc8ba..3c9a149ccc 100644 --- a/politeiawww/cmsdatabase/cockroachdb/models.go +++ b/politeiawww/cmsdatabase/cockroachdb/models.go @@ -68,6 +68,7 @@ type LineItem struct { Expenses uint `gorm:"not null"` // Total cost of line item (in USD cents) ContractorRate uint `gorm:"not null"` // Optional contractor rate for line item, typically used for Sub Contractors SubUserID string `gorm:"not null"` // SubContractor User ID if Subcontractor Line Item + Approved bool `gorm:"not null"` // Proposal owner approved line item } // TableName returns the table name of the line items table. diff --git a/politeiawww/cmsdatabase/database.go b/politeiawww/cmsdatabase/database.go index 07b9635b1a..5c556ea8bc 100644 --- a/politeiawww/cmsdatabase/database.go +++ b/politeiawww/cmsdatabase/database.go @@ -128,6 +128,7 @@ type LineItem struct { Expenses uint ContractorRate uint SubUserID string + Approved bool } // InvoiceChange contains entries for any status update that occurs to a given diff --git a/politeiawww/convert.go b/politeiawww/convert.go index 96604557a5..f2169252ba 100644 --- a/politeiawww/convert.go +++ b/politeiawww/convert.go @@ -869,6 +869,7 @@ func convertDatabaseInvoiceToInvoiceRecord(dbInvoice cmsdatabase.Invoice) (cms.I Expenses: dbLineItem.Expenses, SubRate: dbLineItem.ContractorRate, SubUserID: dbLineItem.SubUserID, + Approved: dbLineItem.Approved, } invInputLineItems = append(invInputLineItems, lineItem) } @@ -924,6 +925,7 @@ func convertInvoiceRecordToDatabaseInvoice(invRec *cms.InvoiceRecord) *cmsdataba Expenses: lineItem.Expenses, ContractorRate: lineItem.SubRate, SubUserID: lineItem.SubUserID, + Approved: lineItem.Approved, } dbInvoice.LineItems = append(dbInvoice.LineItems, dbLineItem) } @@ -944,6 +946,7 @@ func convertLineItemsToDatabase(token string, l []cms.LineItemsInput) []cmsdatab Expenses: v.Expenses, // If subrate is populated, use the existing contractor rate field. ContractorRate: v.SubRate, + Approved: v.Approved, }) } return dl @@ -960,6 +963,7 @@ func convertDatabaseToLineItems(dl []cmsdatabase.LineItem) []cms.LineItemsInput ProposalToken: v.ProposalURL, Labor: v.Labor, Expenses: v.Expenses, + Approved: v.Approved, }) } return l @@ -973,6 +977,7 @@ func convertRecordToDatabaseInvoice(p pd.Record) (*cmsdatabase.Invoice, error) { Version: p.Version, } + var approvedProposals []string // Decode invoice file for _, v := range p.Files { if v.Name == invoiceFile { @@ -1076,12 +1081,11 @@ func convertRecordToDatabaseInvoice(p pd.Record) (*cmsdatabase.Invoice, error) { p.CensorshipRecord.Token, err, m) continue } - var approvedProposals []string for _, s := range ipa { // Check to see if the approved invoice version doesn't match // current invoice version. If so, the proposal owner needs to // approve again. - if s.InvoiceVersion != r.Version { + if s.InvoiceVersion != p.Version { continue } if approvedProposals == nil { @@ -1089,6 +1093,7 @@ func convertRecordToDatabaseInvoice(p pd.Record) (*cmsdatabase.Invoice, error) { } approvedProposals = append(approvedProposals, s.Token) } + default: // Log error but proceed log.Errorf("initializeInventory: invalid "+ @@ -1097,6 +1102,15 @@ func convertRecordToDatabaseInvoice(p pd.Record) (*cmsdatabase.Invoice, error) { } } + // Set all line items to approved based on metadata + for _, approvedProposal := range approvedProposals { + for i := range dbInvoice.LineItems { + if dbInvoice.LineItems[i].ProposalURL == approvedProposal { + dbInvoice.LineItems[i].Approved = true + } + } + } + return &dbInvoice, nil } @@ -1451,6 +1465,7 @@ func convertDatabaseInvoiceToProposalLineItems(inv cmsdatabase.Invoice) cms.Prop Labor: inv.LineItems[0].Labor, Expenses: inv.LineItems[0].Expenses, SubRate: inv.LineItems[0].ContractorRate, + Approved: inv.LineItems[0].Approved, }, } } diff --git a/politeiawww/invoices.go b/politeiawww/invoices.go index 9daa0bd7a7..9b4879617f 100644 --- a/politeiawww/invoices.go +++ b/politeiawww/invoices.go @@ -2128,7 +2128,7 @@ func (p *politeiawww) processProposalInvoiceApprove(poa cms.ProposalOwnerApprove return nil, err } proposalFound := false - for _, lineItem := range invRec.Input.LineItems { + for i, lineItem := range invRec.Input.LineItems { // If the proposal token is empty then don't display it for the // non invoice owner or admin. if lineItem.ProposalToken == "" { @@ -2139,6 +2139,7 @@ func (p *politeiawww) processProposalInvoiceApprove(poa cms.ProposalOwnerApprove // list of line items to display. if stringInSlice(cmsUser.ProposalsOwned, lineItem.ProposalToken) { proposalFound = true + invRec.Input.LineItems[i].Approved = true } } if !proposalFound { @@ -2208,5 +2209,10 @@ func (p *politeiawww) processProposalInvoiceApprove(poa cms.ProposalOwnerApprove return nil, err } + // Update Invoice in db so line items are approved + err = p.cmsDB.UpdateInvoice(convertInvoiceRecordToDatabaseInvoice(invRec)) + if err != nil { + return nil, err + } return &cms.ProposalOwnerApproveReply{}, nil }