quotes

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrQuoteNotFound = fmt.Errorf("quote not found")

ErrQuoteNotFound is returned when a quote is not found

Functions

This section is empty.

Types

type ConvertQuoteToInvoiceRequest

type ConvertQuoteToInvoiceRequest struct {
	IssueDate time.Time `json:"issue_date,omitempty"`
	DueDate   time.Time `json:"due_date,omitempty"`
	Notes     string    `json:"notes,omitempty"`
	UserID    string    `json:"-"`
}

ConvertQuoteToInvoiceRequest requests conversion of an accepted quote into a sales invoice.

type CreateQuoteLineRequest

type CreateQuoteLineRequest struct {
	Description     string          `json:"description"`
	Quantity        decimal.Decimal `json:"quantity"`
	Unit            string          `json:"unit,omitempty"`
	UnitPrice       decimal.Decimal `json:"unit_price"`
	DiscountPercent decimal.Decimal `json:"discount_percent,omitempty"`
	VATRate         decimal.Decimal `json:"vat_rate"`
	ProductID       *string         `json:"product_id,omitempty"`
}

CreateQuoteLineRequest is a line in the create quote request

type CreateQuoteRequest

type CreateQuoteRequest struct {
	ContactID    string                   `json:"contact_id"`
	QuoteDate    time.Time                `json:"quote_date"`
	ValidUntil   *time.Time               `json:"valid_until,omitempty"`
	Currency     string                   `json:"currency,omitempty"`
	ExchangeRate decimal.Decimal          `json:"exchange_rate,omitempty"`
	Notes        string                   `json:"notes,omitempty"`
	Lines        []CreateQuoteLineRequest `json:"lines"`
	UserID       string                   `json:"-"`
}

CreateQuoteRequest is the request to create a quote

type GORMRepository

type GORMRepository struct {
	// contains filtered or unexported fields
}

GORMRepository implements Repository with the shared ORM layer.

func NewGORMRepository

func NewGORMRepository(db *gorm.DB) *GORMRepository

func NewRepository

func NewRepository(db *pgxpool.Pool) *GORMRepository

func (*GORMRepository) Create

func (r *GORMRepository) Create(ctx context.Context, schemaName string, quote *Quote) error

Create inserts a new quote with its lines

func (*GORMRepository) Delete

func (r *GORMRepository) Delete(ctx context.Context, schemaName, tenantID, quoteID string) error

Delete removes a quote (only drafts)

func (*GORMRepository) GenerateNumber

func (r *GORMRepository) GenerateNumber(ctx context.Context, schemaName, tenantID string) (string, error)

GenerateNumber generates a new quote number

func (*GORMRepository) GetByID

func (r *GORMRepository) GetByID(ctx context.Context, schemaName, tenantID, quoteID string) (*Quote, error)

GetByID retrieves a quote by ID with its lines

func (*GORMRepository) List

func (r *GORMRepository) List(ctx context.Context, schemaName, tenantID string, filter *QuoteFilter) ([]Quote, error)

List retrieves quotes with optional filtering

func (*GORMRepository) SetConvertedToInvoice

func (r *GORMRepository) SetConvertedToInvoice(ctx context.Context, schemaName, tenantID, quoteID, invoiceID string) error

SetConvertedToInvoice marks a quote as converted to an invoice

func (*GORMRepository) SetConvertedToOrder

func (r *GORMRepository) SetConvertedToOrder(ctx context.Context, schemaName, tenantID, quoteID, orderID string) error

SetConvertedToOrder marks a quote as converted to an order

func (*GORMRepository) Update

func (r *GORMRepository) Update(ctx context.Context, schemaName string, quote *Quote) error

Update updates a quote and its lines

func (*GORMRepository) UpdateStatus

func (r *GORMRepository) UpdateStatus(ctx context.Context, schemaName, tenantID, quoteID string, status QuoteStatus) error

UpdateStatus updates the status of a quote

type ImportQuotesRequest

type ImportQuotesRequest struct {
	CSVContent string `json:"csv_content"`
	FileName   string `json:"file_name,omitempty"`
	UserID     string `json:"-"`
}

ImportQuotesRequest contains CSV payload for quote migration.

type ImportQuotesResult

type ImportQuotesResult struct {
	FileName      string                 `json:"file_name,omitempty"`
	RowsProcessed int                    `json:"rows_processed"`
	QuotesCreated int                    `json:"quotes_created"`
	LinesImported int                    `json:"lines_imported"`
	RowsSkipped   int                    `json:"rows_skipped"`
	Errors        []ImportQuotesRowError `json:"errors,omitempty"`
}

ImportQuotesResult summarizes a quote CSV import.

type ImportQuotesRowError

type ImportQuotesRowError struct {
	Row         int    `json:"row"`
	QuoteNumber string `json:"quote_number,omitempty"`
	Message     string `json:"message"`
}

ImportQuotesRowError describes a row-level quote import failure.

type Quote

type Quote struct {
	ID                   string            `json:"id"`
	TenantID             string            `json:"tenant_id"`
	QuoteNumber          string            `json:"quote_number"`
	ContactID            string            `json:"contact_id"`
	Contact              *contacts.Contact `json:"contact,omitempty"`
	QuoteDate            time.Time         `json:"quote_date"`
	ValidUntil           *time.Time        `json:"valid_until,omitempty"`
	Status               QuoteStatus       `json:"status"`
	Currency             string            `json:"currency"`
	ExchangeRate         decimal.Decimal   `json:"exchange_rate"`
	Subtotal             decimal.Decimal   `json:"subtotal"`
	VATAmount            decimal.Decimal   `json:"vat_amount"`
	Total                decimal.Decimal   `json:"total"`
	Notes                string            `json:"notes,omitempty"`
	ConvertedToOrderID   *string           `json:"converted_to_order_id,omitempty"`
	ConvertedToInvoiceID *string           `json:"converted_to_invoice_id,omitempty"`
	Lines                []QuoteLine       `json:"lines"`
	CreatedAt            time.Time         `json:"created_at"`
	CreatedBy            string            `json:"created_by"`
	UpdatedAt            time.Time         `json:"updated_at"`
}

Quote represents a sales quote/offer

func (*Quote) Calculate

func (q *Quote) Calculate()

Calculate computes the quote totals from lines

func (*Quote) IsExpired

func (q *Quote) IsExpired() bool

IsExpired returns true if the quote is past its valid date

func (*Quote) Validate

func (q *Quote) Validate() error

Validate validates the quote

type QuoteFilter

type QuoteFilter struct {
	Status    QuoteStatus
	ContactID string
	FromDate  *time.Time
	ToDate    *time.Time
	Search    string
}

QuoteFilter provides filtering options

type QuoteInvoiceConversionResult

type QuoteInvoiceConversionResult struct {
	Quote   *Quote             `json:"quote"`
	Invoice *invoicing.Invoice `json:"invoice"`
}

QuoteInvoiceConversionResult returns the converted quote and created invoice.

type QuoteLine

type QuoteLine struct {
	ID              string          `json:"id"`
	TenantID        string          `json:"tenant_id"`
	QuoteID         string          `json:"quote_id"`
	LineNumber      int             `json:"line_number"`
	Description     string          `json:"description"`
	Quantity        decimal.Decimal `json:"quantity"`
	Unit            string          `json:"unit,omitempty"`
	UnitPrice       decimal.Decimal `json:"unit_price"`
	DiscountPercent decimal.Decimal `json:"discount_percent"`
	VATRate         decimal.Decimal `json:"vat_rate"`
	LineSubtotal    decimal.Decimal `json:"line_subtotal"`
	LineVAT         decimal.Decimal `json:"line_vat"`
	LineTotal       decimal.Decimal `json:"line_total"`
	ProductID       *string         `json:"product_id,omitempty"`
}

QuoteLine represents a line item on a quote

func (*QuoteLine) Calculate

func (l *QuoteLine) Calculate()

Calculate computes the line totals

type QuoteStatus

type QuoteStatus string

QuoteStatus represents the status of a quote

const (
	QuoteStatusDraft     QuoteStatus = "DRAFT"
	QuoteStatusSent      QuoteStatus = "SENT"
	QuoteStatusAccepted  QuoteStatus = "ACCEPTED"
	QuoteStatusRejected  QuoteStatus = "REJECTED"
	QuoteStatusExpired   QuoteStatus = "EXPIRED"
	QuoteStatusConverted QuoteStatus = "CONVERTED"
)

type Repository

type Repository interface {
	Create(ctx context.Context, schemaName string, quote *Quote) error
	GetByID(ctx context.Context, schemaName, tenantID, quoteID string) (*Quote, error)
	List(ctx context.Context, schemaName, tenantID string, filter *QuoteFilter) ([]Quote, error)
	Update(ctx context.Context, schemaName string, quote *Quote) error
	UpdateStatus(ctx context.Context, schemaName, tenantID, quoteID string, status QuoteStatus) error
	Delete(ctx context.Context, schemaName, tenantID, quoteID string) error
	GenerateNumber(ctx context.Context, schemaName, tenantID string) (string, error)
	SetConvertedToOrder(ctx context.Context, schemaName, tenantID, quoteID, orderID string) error
	SetConvertedToInvoice(ctx context.Context, schemaName, tenantID, quoteID, invoiceID string) error
}

Repository defines the contract for quote data access

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service provides quote operations

func NewService

func NewService(db *pgxpool.Pool) *Service

NewService creates a new quotes service with an ORM-backed repository.

func NewServiceWithRepository

func NewServiceWithRepository(repo Repository) *Service

NewServiceWithRepository creates a new quotes service with a custom repository

func (*Service) Accept

func (s *Service) Accept(ctx context.Context, tenantID, schemaName, quoteID string) error

Accept marks a quote as accepted by the customer

func (*Service) ConvertToInvoice

func (s *Service) ConvertToInvoice(ctx context.Context, tenantID, schemaName, quoteID, invoiceID string) error

ConvertToInvoice marks a quote as converted to an invoice

func (*Service) ConvertToOrder

func (s *Service) ConvertToOrder(ctx context.Context, tenantID, schemaName, quoteID, orderID string) error

ConvertToOrder marks a quote as converted to an order

func (*Service) Create

func (s *Service) Create(ctx context.Context, tenantID, schemaName string, req *CreateQuoteRequest) (*Quote, error)

Create creates a new quote

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, tenantID, schemaName, quoteID string) error

Delete deletes a draft quote

func (*Service) GetByID

func (s *Service) GetByID(ctx context.Context, tenantID, schemaName, quoteID string) (*Quote, error)

GetByID retrieves a quote by ID

func (*Service) ImportCSV

func (s *Service) ImportCSV(
	ctx context.Context,
	tenantID, schemaName string,
	existingContacts []contacts.Contact,
	existingProducts []inventory.Product,
	req *ImportQuotesRequest,
) (*ImportQuotesResult, error)

ImportCSV imports historical quotes from grouped CSV rows. Each row represents one quote line.

func (*Service) List

func (s *Service) List(ctx context.Context, tenantID, schemaName string, filter *QuoteFilter) ([]Quote, error)

List retrieves quotes with optional filtering

func (*Service) Reject

func (s *Service) Reject(ctx context.Context, tenantID, schemaName, quoteID string) error

Reject marks a quote as rejected by the customer

func (*Service) Send

func (s *Service) Send(ctx context.Context, tenantID, schemaName, quoteID string) error

Send marks a quote as sent

func (*Service) Update

func (s *Service) Update(ctx context.Context, tenantID, schemaName, quoteID string, req *UpdateQuoteRequest) (*Quote, error)

Update updates a quote (only drafts)

type UpdateQuoteRequest

type UpdateQuoteRequest struct {
	ContactID    string                   `json:"contact_id"`
	QuoteDate    time.Time                `json:"quote_date"`
	ValidUntil   *time.Time               `json:"valid_until,omitempty"`
	Currency     string                   `json:"currency,omitempty"`
	ExchangeRate decimal.Decimal          `json:"exchange_rate,omitempty"`
	Notes        string                   `json:"notes,omitempty"`
	Lines        []CreateQuoteLineRequest `json:"lines"`
}

UpdateQuoteRequest is the request to update a quote

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL