342 lines
9.3 KiB
Go
342 lines
9.3 KiB
Go
package pkg
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/jackc/pgtype"
|
|
"github.com/jackc/pgx/v4"
|
|
)
|
|
|
|
var (
|
|
oidCache = make(map[string]uint32)
|
|
)
|
|
|
|
type CustomerTaxDetails struct {
|
|
BusinessName string
|
|
VATIN string
|
|
Address string
|
|
City string
|
|
Province string
|
|
PostalCode string
|
|
CountryCode string
|
|
}
|
|
|
|
func (src CustomerTaxDetails) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
|
|
typeName := "tax_details"
|
|
dt, ok := ci.DataTypeForName(typeName)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
|
|
}
|
|
values := []interface{}{
|
|
src.BusinessName,
|
|
src.VATIN,
|
|
src.Address,
|
|
src.City,
|
|
src.Province,
|
|
src.PostalCode,
|
|
src.CountryCode,
|
|
}
|
|
ct := pgtype.NewValue(dt.Value).(pgtype.ValueTranscoder)
|
|
if err := ct.Set(values); err != nil {
|
|
return nil, err
|
|
}
|
|
return ct.EncodeBinary(ci, buf)
|
|
}
|
|
|
|
type NewInvoiceProductArray []*invoiceProductForm
|
|
|
|
func (src NewInvoiceProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
|
|
typeName := "new_invoice_product[]"
|
|
dt, ok := ci.DataTypeForName(typeName)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
|
|
}
|
|
var values [][]interface{}
|
|
for _, form := range src {
|
|
var productId interface{} = form.ProductId.Val
|
|
if form.ProductId.Val == "" {
|
|
productId = nil
|
|
}
|
|
values = append(values, []interface{}{
|
|
productId,
|
|
form.Name.Val,
|
|
form.Description.Val,
|
|
form.Price.Val,
|
|
form.Quantity.Val,
|
|
form.Discount.Float64() / 100.0,
|
|
form.Tax.Selected,
|
|
})
|
|
}
|
|
array := pgtype.NewValue(dt.Value).(pgtype.ValueTranscoder)
|
|
if err := array.Set(values); err != nil {
|
|
return nil, err
|
|
}
|
|
return array.EncodeBinary(ci, buf)
|
|
}
|
|
|
|
type EditedInvoiceProductArray []*invoiceProductForm
|
|
|
|
func (src EditedInvoiceProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
|
|
typeName := "edited_invoice_product[]"
|
|
dt, ok := ci.DataTypeForName(typeName)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
|
|
}
|
|
var values [][]interface{}
|
|
for _, form := range src {
|
|
values = append(values, []interface{}{
|
|
form.InvoiceProductId.IntegerOrNil(),
|
|
form.ProductId.IntegerOrNil(),
|
|
form.Name.Val,
|
|
form.Description.Val,
|
|
form.Price.Val,
|
|
form.Quantity.Val,
|
|
form.Discount.Float64() / 100.0,
|
|
form.Tax.Selected,
|
|
})
|
|
}
|
|
array := pgtype.NewValue(dt.Value).(pgtype.ValueTranscoder)
|
|
if err := array.Set(values); err != nil {
|
|
return nil, err
|
|
}
|
|
return array.EncodeBinary(ci, buf)
|
|
}
|
|
|
|
type NewQuoteProductArray []*quoteProductForm
|
|
|
|
func (src NewQuoteProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
|
|
typeName := "new_quote_product[]"
|
|
dt, ok := ci.DataTypeForName(typeName)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
|
|
}
|
|
var values [][]interface{}
|
|
for _, form := range src {
|
|
var productId interface{} = form.ProductId.Val
|
|
if form.ProductId.Val == "" {
|
|
productId = nil
|
|
}
|
|
values = append(values, []interface{}{
|
|
productId,
|
|
form.Name.Val,
|
|
form.Description.Val,
|
|
form.Price.Val,
|
|
form.Quantity.Val,
|
|
form.Discount.Float64() / 100.0,
|
|
form.Tax.Selected,
|
|
})
|
|
}
|
|
array := pgtype.NewValue(dt.Value).(pgtype.ValueTranscoder)
|
|
if err := array.Set(values); err != nil {
|
|
return nil, err
|
|
}
|
|
return array.EncodeBinary(ci, buf)
|
|
}
|
|
|
|
type EditedQuoteProductArray []*quoteProductForm
|
|
|
|
func (src EditedQuoteProductArray) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
|
|
typeName := "edited_quote_product[]"
|
|
dt, ok := ci.DataTypeForName(typeName)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unable to find oid for type name %v", typeName)
|
|
}
|
|
var values [][]interface{}
|
|
for _, form := range src {
|
|
values = append(values, []interface{}{
|
|
form.QuoteProductId.IntegerOrNil(),
|
|
form.ProductId.IntegerOrNil(),
|
|
form.Name.Val,
|
|
form.Description.Val,
|
|
form.Price.Val,
|
|
form.Quantity.Val,
|
|
form.Discount.Float64() / 100.0,
|
|
form.Tax.Selected,
|
|
})
|
|
}
|
|
array := pgtype.NewValue(dt.Value).(pgtype.ValueTranscoder)
|
|
if err := array.Set(values); err != nil {
|
|
return nil, err
|
|
}
|
|
return array.EncodeBinary(ci, buf)
|
|
}
|
|
|
|
func registerPgTypes(ctx context.Context, conn *pgx.Conn) error {
|
|
if _, err := conn.Exec(ctx, "set role to admin"); err != nil {
|
|
return err
|
|
}
|
|
tagNameOID, err := registerPgType(ctx, conn, &pgtype.Text{}, "tag_name")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tagNameArray := pgtype.NewArrayType("tag_name[]", tagNameOID, func() pgtype.ValueTranscoder {
|
|
return &pgtype.Text{}
|
|
})
|
|
if _, err := registerPgType(ctx, conn, tagNameArray, tagNameArray.TypeName()); err != nil {
|
|
return err
|
|
}
|
|
discountRateOID, err := registerPgType(ctx, conn, &pgtype.Numeric{}, "discount_rate")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
newInvoiceProduct, err := pgtype.NewCompositeType(
|
|
"new_invoice_product",
|
|
[]pgtype.CompositeTypeField{
|
|
{"product_id", pgtype.Int4OID},
|
|
{"name", pgtype.TextOID},
|
|
{"description", pgtype.TextOID},
|
|
{"price", pgtype.TextOID},
|
|
{"quantity", pgtype.Int4OID},
|
|
{"discount_rate", discountRateOID},
|
|
{"tax", pgtype.Int4ArrayOID},
|
|
},
|
|
conn.ConnInfo(),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
newInvoiceProductOID, err := registerPgType(ctx, conn, newInvoiceProduct, newInvoiceProduct.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
newInvoiceProductArray := pgtype.NewArrayType("new_invoice_product[]", newInvoiceProductOID, func() pgtype.ValueTranscoder {
|
|
value := newInvoiceProduct.NewTypeValue()
|
|
return value.(pgtype.ValueTranscoder)
|
|
})
|
|
_, err = registerPgType(ctx, conn, newInvoiceProductArray, newInvoiceProductArray.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
editedInvoiceProduct, err := pgtype.NewCompositeType(
|
|
"edited_invoice_product",
|
|
[]pgtype.CompositeTypeField{
|
|
{"invoice_product_id", pgtype.Int4OID},
|
|
{"product_id", pgtype.Int4OID},
|
|
{"name", pgtype.TextOID},
|
|
{"description", pgtype.TextOID},
|
|
{"price", pgtype.TextOID},
|
|
{"quantity", pgtype.Int4OID},
|
|
{"discount_rate", discountRateOID},
|
|
{"tax", pgtype.Int4ArrayOID},
|
|
},
|
|
conn.ConnInfo(),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
editedInvoiceProductOID, err := registerPgType(ctx, conn, editedInvoiceProduct, editedInvoiceProduct.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
editedInvoiceProductArray := pgtype.NewArrayType("edited_invoice_product[]", editedInvoiceProductOID, func() pgtype.ValueTranscoder {
|
|
value := editedInvoiceProduct.NewTypeValue()
|
|
return value.(pgtype.ValueTranscoder)
|
|
})
|
|
_, err = registerPgType(ctx, conn, editedInvoiceProductArray, editedInvoiceProductArray.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
newQuoteProduct, err := pgtype.NewCompositeType(
|
|
"new_quote_product",
|
|
[]pgtype.CompositeTypeField{
|
|
{"product_id", pgtype.Int4OID},
|
|
{"name", pgtype.TextOID},
|
|
{"description", pgtype.TextOID},
|
|
{"price", pgtype.TextOID},
|
|
{"quantity", pgtype.Int4OID},
|
|
{"discount_rate", discountRateOID},
|
|
{"tax", pgtype.Int4ArrayOID},
|
|
},
|
|
conn.ConnInfo(),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
newQuoteProductOID, err := registerPgType(ctx, conn, newQuoteProduct, newQuoteProduct.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
newQuoteProductArray := pgtype.NewArrayType("new_quote_product[]", newQuoteProductOID, func() pgtype.ValueTranscoder {
|
|
value := newQuoteProduct.NewTypeValue()
|
|
return value.(pgtype.ValueTranscoder)
|
|
})
|
|
_, err = registerPgType(ctx, conn, newQuoteProductArray, newQuoteProductArray.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
editedQuoteProduct, err := pgtype.NewCompositeType(
|
|
"edited_quote_product",
|
|
[]pgtype.CompositeTypeField{
|
|
{"quote_product_id", pgtype.Int4OID},
|
|
{"product_id", pgtype.Int4OID},
|
|
{"name", pgtype.TextOID},
|
|
{"description", pgtype.TextOID},
|
|
{"price", pgtype.TextOID},
|
|
{"quantity", pgtype.Int4OID},
|
|
{"discount_rate", discountRateOID},
|
|
{"tax", pgtype.Int4ArrayOID},
|
|
},
|
|
conn.ConnInfo(),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
editedQuoteProductOID, err := registerPgType(ctx, conn, editedQuoteProduct, editedQuoteProduct.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
editedQuoteProductArray := pgtype.NewArrayType("edited_quote_product[]", editedQuoteProductOID, func() pgtype.ValueTranscoder {
|
|
value := editedQuoteProduct.NewTypeValue()
|
|
return value.(pgtype.ValueTranscoder)
|
|
})
|
|
_, err = registerPgType(ctx, conn, editedQuoteProductArray, editedQuoteProductArray.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
countryCodeOID, err := registerPgType(ctx, conn, &pgtype.Text{}, "country_code")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
taxDetailsType, err := pgtype.NewCompositeType(
|
|
"tax_details",
|
|
[]pgtype.CompositeTypeField{
|
|
{"business_name", pgtype.TextOID},
|
|
{"vatin", pgtype.TextOID},
|
|
{"address", pgtype.TextOID},
|
|
{"city", pgtype.TextOID},
|
|
{"province", pgtype.TextOID},
|
|
{"postal_code", pgtype.TextOID},
|
|
{"discount_rate", countryCodeOID},
|
|
},
|
|
conn.ConnInfo(),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = registerPgType(ctx, conn, taxDetailsType, taxDetailsType.TypeName())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = conn.Exec(ctx, "reset role")
|
|
return err
|
|
}
|
|
|
|
func registerPgType(ctx context.Context, conn *pgx.Conn, value pgtype.Value, name string) (oid uint32, err error) {
|
|
var found bool
|
|
if oid, found = oidCache[name]; !found {
|
|
if err = conn.QueryRow(ctx, "select $1::regtype::oid", name).Scan(&oid); err != nil {
|
|
return
|
|
}
|
|
oidCache[name] = oid
|
|
}
|
|
conn.ConnInfo().RegisterDataType(pgtype.DataType{Value: value, Name: name, OID: oid})
|
|
return
|
|
}
|