func (i *Invoice) Clear() {
	i.SubTotal = 0
	i.Discount = 0
	i.Tax = 0
	i.ServiceFee = 0
	i.InstallmentFee = 0
	i.State = Draft
	i.LineItems = []LineItem{}
	i.Payment = nil
}
Clear remove all invoice values (subtotal, discount, tax, fee, line item and payment method)
and reset the state to draft
package invoice
import (
	"context"
	"encoding/json"
	"time"
	"gorm.io/gorm"
	"github.com/imrenagi/go-payment"
	"github.com/imrenagi/go-payment/config"
	"github.com/google/uuid"
)
func newInvoiceNumber() string {
	return uuid.New().String()
}
func NewDefault() *Invoice {
	now := time.Now()
	inv := New(now, now.AddDate(0, 0, 1))
	return inv
}
func New(invoiceDate, dueDate time.Time) *Invoice {
	return &Invoice{
		Number:          newInvoiceNumber(),
		InvoiceDate:     invoiceDate,
		DueDate:         dueDate,
		Currency:        "IDR",
		State:           Draft,
		StateController: &DraftState{},
	}
}
type Invoice struct {
	payment.Model
	Title           string          `json:"-"`
	Number          string          `json:"number" gorm:"unique_index:inv_number_k"`
	InvoiceDate     time.Time       `json:"invoice_date"`
	DueDate         time.Time       `json:"due_date"`
	PaidAt          *time.Time      `json:"paid_at"`
	Currency        string          `json:"-"`
	SubTotal        float64         `json:"-"`
	Discount        float64         `json:"-"`
	Tax             float64         `json:"-"`
	ServiceFee      float64         `json:"-"`
	InstallmentFee  float64         `json:"-"`
	State           State           `json:"-"`
	StateController StateController `json:"-" gorm:"-"`
	LineItems       []LineItem      `json:"items"`
	Payment         *Payment        `json:"payment" gorm:"ForeignKey:InvoiceID"`
	BillingAddress  *BillingAddress `json:"billing_address" gorm:"ForeignKey:InvoiceID"`
	SubscriptionID  *uint64         `json:"-" gorm:"sql:index;"`
}
func (i *Invoice) GetTitle() string {
	return i.Title
}
func (i *Invoice) MarshalJSON() ([]byte, error) {
	type Alias Invoice
	type value struct {
		Currency       string  `json:"currency"`
		Total          float64 `json:"total_amount"`
		SubTotal       float64 `json:"sub_total_amount"`
		Discount       float64 `json:"discount_amount"`
		Tax            float64 `json:"tax_amount"`
		ServiceFee     float64 `json:"admin_fee_amount"`
		InstallmentFee float64 `json:"installment_fee_amount"`
	}
	return json.Marshal(&struct {
		*Alias
		InvTitle string `json:"title"`
		State    string `json:"state"`
		Value    value  `json:"transaction_values"`
	}{
		Alias:    (*Alias)(i),
		InvTitle: i.GetTitle(),
		State:    i.GetState().String(),
		Value: value{
			Currency:       i.Currency,
			Total:          i.GetTotal(),
			SubTotal:       i.SubTotal,
			Discount:       i.Discount,
			Tax:            i.Tax,
			ServiceFee:     i.ServiceFee,
			InstallmentFee: i.InstallmentFee,
		},
	})
}
func (i *Invoice) GetTotal() float64 {
	return i.SubTotal + i.Tax + i.ServiceFee + i.InstallmentFee - i.Discount
}
type paymentMethodFinder interface {
	FindByPaymentType(ctx context.Context, paymentType payment.PaymentType, opts ...payment.Option) (config.FeeConfigReader, error)
}