Files
commerce/models/product/document.go
zeekay 1943f1c093 Hanzo Commerce
Multi-tenant commerce and billing: orders, subscriptions, invoices, plans,
usage metering and a credit ledger. One Go binary. MIT OR Apache-2.0.

Claude-Session: https://claude.ai/code/session_01SAtaDFm8VDiWrhYHNNtxMw
2026-09-23 21:52:16 -07:00

141 lines
3.6 KiB
Go

package product
import (
"github.com/hanzoai/commerce/models/mixin"
"github.com/hanzoai/commerce/models/types/currency"
)
type Document struct {
mixin.DocumentSaveLoad `datastore:"-" json:"-"`
// Special Kind Option
Kind string `search:",facet"`
Id_ string
Slug string
SKU string
UPC string
Currency string
Price float64
ListPrice float64
InventoryCost float64
// Shipping float64
Inventory float64
Weight float64
WeightUnit string
DimensionsLength float64
DimensionsWidth float64
DimensionsHeight float64
DimensionsUnit string
Name string
Description string
EstimatedDelivery string
CreatedAt float64
UpdatedAt float64
// Facets
PriceOption float64 `search:"price,facet"`
ListPriceOption float64 `search:"listPrice,facet"`
InventoryCostOption float64 `search:"inventoryCost,facet"`
InventoryOption float64 `search:"inventory,facet"`
WeightOption float64 `search:"weight,facet"`
WeightUnitOption string `search:"weightUnit,facet"`
DimensionsLengthOption float64 `search:"dimensionsLength,facet"`
DimensionsWidthOption float64 `search:"dimensionsWidth,facet"`
DimensionsHeightOption float64 `search:"dimensionsHeight,facet"`
DimensionsUnitOption string `search:"dimensionsUnit,facet"`
AvailableOption string `search:"available,facet"`
HiddenOption string `search:"hidden,facet"`
PreorderOption string `search:"preorder,facet"`
}
func (d *Document) Id() string {
return d.Id_
}
func (d *Document) Init() {
d.SetDocument(d)
}
func (p Product) Document() mixin.Document {
doc := &Document{}
doc.Init()
doc.Kind = "product"
doc.Id_ = p.Id()
doc.Slug = p.Slug
doc.SKU = p.SKU
doc.UPC = p.UPC
doc.Currency = string(p.Currency)
// A search document is a projection, not a record. The index sorts and
// range-filters on price, which is what a number buys us, so these stay
// float64 and AsMajorUnits is spelled out at each one to make the crossing
// visible. The product keeps integer cents — nothing reads a price back out
// of the index.
doc.Price = p.Currency.Amount(p.Price).AsMajorUnits()
doc.ListPrice = p.Currency.Amount(p.ListPrice).AsMajorUnits()
doc.InventoryCost = p.Currency.Amount(p.InventoryCost).AsMajorUnits()
// doc.Shipping = float64(p.Shipping)
doc.Inventory = float64(p.Inventory)
doc.Weight = float64(p.Weight)
doc.WeightUnit = string(p.WeightUnit)
doc.DimensionsLength = float64(p.Dimensions.Length)
doc.DimensionsWidth = float64(p.Dimensions.Width)
doc.DimensionsHeight = float64(p.Dimensions.Height)
doc.DimensionsUnit = string(p.DimensionsUnit)
doc.Name = p.Name
doc.Description = p.Description
doc.EstimatedDelivery = p.EstimatedDelivery
doc.CreatedAt = float64(p.CreatedAt.Unix())
doc.UpdatedAt = float64(p.UpdatedAt.Unix())
switch p.Currency {
case currency.ETH, currency.BTC, currency.XBT:
doc.PriceOption = float64(p.Price) / 1e9
doc.ListPriceOption = float64(p.ListPrice) / 1e9
doc.InventoryCostOption = float64(p.InventoryCost) / 1e9
default:
doc.PriceOption = float64(p.Price)
doc.ListPriceOption = float64(p.ListPrice)
doc.InventoryCostOption = float64(p.InventoryCost)
}
doc.InventoryOption = float64(p.Inventory)
doc.WeightOption = float64(p.Weight)
doc.WeightUnitOption = string(p.WeightUnit)
doc.DimensionsLengthOption = p.Dimensions.Length
doc.DimensionsWidthOption = p.Dimensions.Width
doc.DimensionsHeightOption = p.Dimensions.Height
doc.DimensionsUnitOption = string(p.DimensionsUnit)
if p.Available {
doc.AvailableOption = "available"
}
if p.Hidden {
doc.HiddenOption = "hidden"
}
if p.Preorder {
doc.PreorderOption = "preorder"
}
return doc
}