diff --git a/go/internal/cmc/db/models.go b/go/internal/cmc/db/models.go index 8a1c73a9..954bb631 100644 --- a/go/internal/cmc/db/models.go +++ b/go/internal/cmc/db/models.go @@ -342,17 +342,20 @@ type Quote struct { // limited at 5 digits. Really, you're not going to have more revisions of a single quote than that Revision int32 `json:"revision"` // estimated delivery time for quote - DeliveryTime string `json:"delivery_time"` - DeliveryTimeFrame string `json:"delivery_time_frame"` - PaymentTerms string `json:"payment_terms"` - DaysValid int32 `json:"days_valid"` - DateIssued time.Time `json:"date_issued"` - ValidUntil time.Time `json:"valid_until"` - DeliveryPoint string `json:"delivery_point"` - ExchangeRate string `json:"exchange_rate"` - CustomsDuty string `json:"customs_duty"` - DocumentID int32 `json:"document_id"` - CommercialComments sql.NullString `json:"commercial_comments"` + DeliveryTime string `json:"delivery_time"` + DeliveryTimeFrame string `json:"delivery_time_frame"` + PaymentTerms string `json:"payment_terms"` + DaysValid int32 `json:"days_valid"` + DateIssued time.Time `json:"date_issued"` + ValidUntil time.Time `json:"valid_until"` + RemindersDisabled sql.NullBool `json:"reminders_disabled"` + RemindersDisabledAt sql.NullTime `json:"reminders_disabled_at"` + RemindersDisabledBy sql.NullString `json:"reminders_disabled_by"` + DeliveryPoint string `json:"delivery_point"` + ExchangeRate string `json:"exchange_rate"` + CustomsDuty string `json:"customs_duty"` + DocumentID int32 `json:"document_id"` + CommercialComments sql.NullString `json:"commercial_comments"` } type QuoteReminder struct { diff --git a/go/internal/cmc/db/querier.go b/go/internal/cmc/db/querier.go index eae28a35..920fae0f 100644 --- a/go/internal/cmc/db/querier.go +++ b/go/internal/cmc/db/querier.go @@ -43,6 +43,7 @@ type Querier interface { DeletePurchaseOrder(ctx context.Context, id int32) error DeleteState(ctx context.Context, id int32) error DeleteStatus(ctx context.Context, id int32) error + DisableQuoteReminders(ctx context.Context, arg DisableQuoteRemindersParams) (sql.Result, error) GetAddress(ctx context.Context, id int32) (Address, error) GetAllCountries(ctx context.Context) ([]Country, error) GetAllPrinciples(ctx context.Context) ([]Principle, error) @@ -76,6 +77,7 @@ type Querier interface { GetPurchaseOrderRevisions(ctx context.Context, parentPurchaseOrderID int32) ([]PurchaseOrder, error) GetPurchaseOrdersByPrinciple(ctx context.Context, arg GetPurchaseOrdersByPrincipleParams) ([]PurchaseOrder, error) GetQuoteRemindersByType(ctx context.Context, arg GetQuoteRemindersByTypeParams) ([]QuoteReminder, error) + GetQuoteRemindersDisabled(ctx context.Context, id int32) (GetQuoteRemindersDisabledRow, error) GetRecentDocuments(ctx context.Context, limit int32) ([]GetRecentDocumentsRow, error) GetRecentlyExpiredQuotes(ctx context.Context, dateSUB interface{}) ([]GetRecentlyExpiredQuotesRow, error) GetRecentlyExpiredQuotesOnDay(ctx context.Context, dateSUB interface{}) ([]GetRecentlyExpiredQuotesOnDayRow, error) diff --git a/go/internal/cmc/db/quotes.sql.go b/go/internal/cmc/db/quotes.sql.go index 983c3f6d..d9452db2 100644 --- a/go/internal/cmc/db/quotes.sql.go +++ b/go/internal/cmc/db/quotes.sql.go @@ -11,6 +11,23 @@ import ( "time" ) +const disableQuoteReminders = `-- name: DisableQuoteReminders :execresult +UPDATE quotes +SET reminders_disabled = TRUE, + reminders_disabled_at = NOW(), + reminders_disabled_by = ? +WHERE id = ? +` + +type DisableQuoteRemindersParams struct { + RemindersDisabledBy sql.NullString `json:"reminders_disabled_by"` + ID int32 `json:"id"` +} + +func (q *Queries) DisableQuoteReminders(ctx context.Context, arg DisableQuoteRemindersParams) (sql.Result, error) { + return q.db.ExecContext(ctx, disableQuoteReminders, arg.RemindersDisabledBy, arg.ID) +} + const getExpiringSoonQuotes = `-- name: GetExpiringSoonQuotes :many WITH ranked_reminders AS ( SELECT @@ -61,6 +78,7 @@ WHERE q.valid_until >= CURRENT_DATE AND q.valid_until <= DATE_ADD(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until ` @@ -164,6 +182,7 @@ WHERE q.valid_until >= CURRENT_DATE AND q.valid_until = DATE_ADD(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until ` @@ -258,6 +277,25 @@ func (q *Queries) GetQuoteRemindersByType(ctx context.Context, arg GetQuoteRemin return items, nil } +const getQuoteRemindersDisabled = `-- name: GetQuoteRemindersDisabled :one +SELECT reminders_disabled, reminders_disabled_at, reminders_disabled_by +FROM quotes +WHERE id = ? +` + +type GetQuoteRemindersDisabledRow struct { + RemindersDisabled sql.NullBool `json:"reminders_disabled"` + RemindersDisabledAt sql.NullTime `json:"reminders_disabled_at"` + RemindersDisabledBy sql.NullString `json:"reminders_disabled_by"` +} + +func (q *Queries) GetQuoteRemindersDisabled(ctx context.Context, id int32) (GetQuoteRemindersDisabledRow, error) { + row := q.db.QueryRowContext(ctx, getQuoteRemindersDisabled, id) + var i GetQuoteRemindersDisabledRow + err := row.Scan(&i.RemindersDisabled, &i.RemindersDisabledAt, &i.RemindersDisabledBy) + return i, err +} + const getRecentlyExpiredQuotes = `-- name: GetRecentlyExpiredQuotes :many WITH ranked_reminders AS ( SELECT @@ -308,6 +346,7 @@ WHERE q.valid_until < CURRENT_DATE AND valid_until >= DATE_SUB(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until DESC ` @@ -411,6 +450,7 @@ WHERE q.valid_until < CURRENT_DATE AND valid_until = DATE_SUB(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until DESC ` diff --git a/go/internal/cmc/email/email.go b/go/internal/cmc/email/email.go index 03e6ef92..270cad41 100644 --- a/go/internal/cmc/email/email.go +++ b/go/internal/cmc/email/email.go @@ -65,13 +65,20 @@ func (es *EmailService) SendTemplateEmail(to string, subject string, templateNam func (es *EmailService) SendTemplateEmailWithAttachments(to string, subject string, templateName string, data interface{}, ccs []string, bccs []string, attachments []interface{}) error { // Convert interface{} attachments to []Attachment var typedAttachments []Attachment - for _, att := range attachments { + fmt.Printf("DEBUG: Received %d attachments to convert\n", len(attachments)) + for i, att := range attachments { + fmt.Printf("DEBUG: Attachment %d type: %T\n", i, att) if a, ok := att.(Attachment); ok { + fmt.Printf("DEBUG: Converted to Attachment type: %s -> %s\n", a.Filename, a.FilePath) typedAttachments = append(typedAttachments, a) } else if a, ok := att.(struct{ Filename, FilePath string }); ok { + fmt.Printf("DEBUG: Converted from anonymous struct: %s -> %s\n", a.Filename, a.FilePath) typedAttachments = append(typedAttachments, Attachment{Filename: a.Filename, FilePath: a.FilePath}) + } else { + fmt.Printf("DEBUG: Failed to convert attachment type %T\n", att) } } + fmt.Printf("DEBUG: Final typed attachments count: %d\n", len(typedAttachments)) defaultBccs := []string{"carpis@cmctechnologies.com.au"} bccs = append(defaultBccs, bccs...) diff --git a/go/sql/migrations/002_add_reminders_disabled_to_quotes.sql b/go/sql/migrations/002_add_reminders_disabled_to_quotes.sql new file mode 100644 index 00000000..2d82749f --- /dev/null +++ b/go/sql/migrations/002_add_reminders_disabled_to_quotes.sql @@ -0,0 +1,22 @@ +-- +goose Up +-- Add reminders_disabled field to quotes table +ALTER TABLE quotes + ADD COLUMN reminders_disabled BOOLEAN DEFAULT FALSE AFTER valid_until, + ADD COLUMN reminders_disabled_at DATETIME DEFAULT NULL AFTER reminders_disabled, + ADD COLUMN reminders_disabled_by VARCHAR(100) DEFAULT NULL AFTER reminders_disabled_at; + +-- +goose StatementBegin +CREATE INDEX idx_reminders_disabled ON quotes(reminders_disabled); +-- +goose StatementEnd + +-- +goose Down +-- Remove index +-- +goose StatementBegin +DROP INDEX idx_reminders_disabled ON quotes; +-- +goose StatementEnd + +-- Remove columns from quotes +ALTER TABLE quotes + DROP COLUMN reminders_disabled_by, + DROP COLUMN reminders_disabled_at, + DROP COLUMN reminders_disabled; diff --git a/go/sql/queries/quotes.sql b/go/sql/queries/quotes.sql index 9f5fc283..0acba1f1 100644 --- a/go/sql/queries/quotes.sql +++ b/go/sql/queries/quotes.sql @@ -48,6 +48,7 @@ WHERE q.valid_until >= CURRENT_DATE AND q.valid_until <= DATE_ADD(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until; @@ -101,6 +102,7 @@ WHERE q.valid_until >= CURRENT_DATE AND q.valid_until = DATE_ADD(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until; @@ -154,6 +156,7 @@ WHERE q.valid_until < CURRENT_DATE AND valid_until >= DATE_SUB(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until DESC; @@ -207,6 +210,7 @@ WHERE q.valid_until < CURRENT_DATE AND valid_until = DATE_SUB(CURRENT_DATE, INTERVAL ? DAY) AND e.status_id = 5 + AND (q.reminders_disabled IS NULL OR q.reminders_disabled = FALSE) ORDER BY q.valid_until DESC; @@ -218,4 +222,16 @@ ORDER BY date_sent; -- name: InsertQuoteReminder :execresult INSERT INTO quote_reminders (quote_id, reminder_type, date_sent, username) -VALUES (?, ?, ?, ?); \ No newline at end of file +VALUES (?, ?, ?, ?); + +-- name: DisableQuoteReminders :execresult +UPDATE quotes +SET reminders_disabled = TRUE, + reminders_disabled_at = NOW(), + reminders_disabled_by = ? +WHERE id = ?; + +-- name: GetQuoteRemindersDisabled :one +SELECT reminders_disabled, reminders_disabled_at, reminders_disabled_by +FROM quotes +WHERE id = ?; \ No newline at end of file diff --git a/go/sql/schema/014_quotes.sql b/go/sql/schema/014_quotes.sql index d98b8d4d..2e920637 100644 --- a/go/sql/schema/014_quotes.sql +++ b/go/sql/schema/014_quotes.sql @@ -13,6 +13,9 @@ CREATE TABLE IF NOT EXISTS `quotes` ( `days_valid` int(3) NOT NULL, `date_issued` date NOT NULL, `valid_until` date NOT NULL, + `reminders_disabled` tinyint(1) DEFAULT 0, + `reminders_disabled_at` datetime DEFAULT NULL, + `reminders_disabled_by` varchar(100) DEFAULT NULL, `delivery_point` varchar(400) NOT NULL, `exchange_rate` varchar(255) NOT NULL, `customs_duty` varchar(255) NOT NULL, diff --git a/go/templates/quotes/index.html b/go/templates/quotes/index.html index ff23fe0c..e005f584 100644 --- a/go/templates/quotes/index.html +++ b/go/templates/quotes/index.html @@ -71,6 +71,8 @@
  • +
  • +
  • @@ -151,6 +153,8 @@
  • +
  • +
  • @@ -188,9 +192,35 @@ + + +