Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit 09c1138

Browse files
authored
Merge pull request #1995 from OpenBazaar/1983-order-total-w-normalized-listings
(#1983) Calculate order total w normalized listings
2 parents 9fdc036 + 84a572a commit 09c1138

File tree

4 files changed

+347
-73
lines changed

4 files changed

+347
-73
lines changed

core/order.go

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -905,54 +905,61 @@ func (n *OpenBazaarNode) CalcOrderID(order *pb.Order) (string, error) {
905905
func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (*big.Int, error) {
906906
var (
907907
total = big.NewInt(0)
908-
physicalGoods = make(map[string]*pb.Listing)
908+
physicalGoods = make(map[string]*repo.Listing)
909909
toHundredths = func(f float32) *big.Float {
910910
return new(big.Float).Mul(big.NewFloat(float64(f)), big.NewFloat(0.01))
911911
}
912+
v5Order, err = repo.ToV5Order(contract.BuyerOrder, n.LookupCurrency)
912913
)
914+
if err != nil {
915+
return big.NewInt(0), fmt.Errorf("normalizing buyer order: %s", err.Error())
916+
}
913917

914-
for _, item := range contract.BuyerOrder.Items {
918+
for _, item := range v5Order.Items {
915919
var itemOriginAmt *repo.CurrencyValue
916920
l, err := ParseContractForListing(item.ListingHash, contract)
917921
if err != nil {
918922
return big.NewInt(0), fmt.Errorf("listing not found in contract for item %s", item.ListingHash)
919923
}
920924

921-
// keep track of physical listings for shipping caluclation
922-
if l.Metadata.ContractType == pb.Listing_Metadata_PHYSICAL_GOOD {
923-
physicalGoods[item.ListingHash] = l
924-
}
925-
926925
rl, err := repo.NewListingFromProtobuf(l)
927926
if err != nil {
928927
return big.NewInt(0), err
929928
}
930929

930+
nrl, err := rl.Normalize()
931+
if err != nil {
932+
return big.NewInt(0), fmt.Errorf("normalize legacy listing: %s", err.Error())
933+
}
934+
935+
// keep track of physical listings for shipping caluclation
936+
if nrl.GetContractType() == pb.Listing_Metadata_PHYSICAL_GOOD.String() {
937+
physicalGoods[item.ListingHash] = nrl
938+
}
939+
931940
// calculate base amount
932-
if l.Metadata.ContractType == pb.Listing_Metadata_CRYPTOCURRENCY &&
933-
l.Metadata.Format == pb.Listing_Metadata_MARKET_PRICE {
934-
var originDef = repo.NewUnknownCryptoDefinition(l.Metadata.CryptoCurrencyCode, 0)
935-
itemOriginAmt = repo.NewCurrencyValueFromBigInt(GetOrderQuantity(l, item), originDef)
936-
937-
if l.Metadata.PriceModifier != 0 {
938-
itemOriginAmt = itemOriginAmt.AddBigFloatProduct(toHundredths(l.Metadata.PriceModifier))
939-
} else if l.Item.PriceModifier != 0 {
940-
itemOriginAmt = itemOriginAmt.AddBigFloatProduct(toHundredths(l.Item.PriceModifier))
941+
if nrl.GetContractType() == pb.Listing_Metadata_CRYPTOCURRENCY.String() &&
942+
nrl.GetFormat() == pb.Listing_Metadata_MARKET_PRICE.String() {
943+
var originDef = repo.NewUnknownCryptoDefinition(nrl.GetCryptoCurrencyCode(), 0)
944+
itemOriginAmt = repo.NewCurrencyValueFromBigInt(GetOrderQuantity(nrl.GetProtobuf(), item), originDef)
945+
946+
if priceModifier := nrl.GetPriceModifier(); priceModifier != 0 {
947+
itemOriginAmt = itemOriginAmt.AddBigFloatProduct(toHundredths(priceModifier))
941948
}
942949
} else {
943-
oAmt, err := repo.NewCurrencyValueFromProtobuf(l.Item.BigPrice, l.Item.PriceCurrency)
950+
oAmt, err := nrl.GetPrice()
944951
if err != nil {
945952
return big.NewInt(0), err
946953
}
947954
itemOriginAmt = oAmt
948955
}
949956

950957
// apply surcharges
951-
selectedSku, err := GetSelectedSku(l, item.Options)
958+
selectedSku, err := GetSelectedSku(nrl.GetProtobuf(), item.Options)
952959
if err != nil {
953960
return big.NewInt(0), err
954961
}
955-
skus, err := rl.GetSkus()
962+
skus, err := nrl.GetSkus()
956963
if err != nil {
957964
return big.NewInt(0), err
958965
}
@@ -973,7 +980,7 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (*b
973980
if err != nil {
974981
return big.NewInt(0), err
975982
}
976-
for _, vendorCoupon := range l.Coupons {
983+
for _, vendorCoupon := range nrl.GetProtobuf().Coupons {
977984
if id.B58String() == vendorCoupon.GetHash() {
978985
if disc, ok := new(big.Int).SetString(vendorCoupon.BigPriceDiscount, 10); ok && disc.Cmp(big.NewInt(0)) > 0 {
979986
// apply fixed discount
@@ -987,7 +994,7 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (*b
987994
}
988995

989996
// apply taxes
990-
for _, tax := range l.Taxes {
997+
for _, tax := range nrl.GetProtobuf().Taxes {
991998
for _, taxRegion := range tax.TaxRegions {
992999
if contract.BuyerOrder.Shipping.Country == taxRegion {
9931000
itemOriginAmt = itemOriginAmt.AddBigFloatProduct(toHundredths(tax.Percentage))
@@ -997,9 +1004,9 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (*b
9971004
}
9981005

9991006
// apply requested quantity
1000-
if !(l.Metadata.ContractType == pb.Listing_Metadata_CRYPTOCURRENCY &&
1001-
l.Metadata.Format == pb.Listing_Metadata_MARKET_PRICE) {
1002-
if itemQuantity := GetOrderQuantity(l, item); itemQuantity.Cmp(big.NewInt(0)) > 0 {
1007+
if !(nrl.GetContractType() == pb.Listing_Metadata_CRYPTOCURRENCY.String() &&
1008+
nrl.GetFormat() == pb.Listing_Metadata_MARKET_PRICE.String()) {
1009+
if itemQuantity := GetOrderQuantity(nrl.GetProtobuf(), item); itemQuantity.Cmp(big.NewInt(0)) > 0 {
10031010
itemOriginAmt = itemOriginAmt.MulBigInt(itemQuantity)
10041011
} else {
10051012
log.Debugf("missing quantity for order, assuming quantity 1")
@@ -1012,7 +1019,7 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (*b
10121019
return big.NewInt(0), fmt.Errorf("preparing reserve currency converter: %s", err.Error())
10131020
}
10141021

1015-
finalItemAmount, err := itemOriginAmt.ConvertUsingProtobufDef(contract.BuyerOrder.Payment.AmountCurrency, cc)
1022+
finalItemAmount, _, err := itemOriginAmt.ConvertUsingProtobufDef(v5Order.Payment.AmountCurrency, cc)
10161023
if err != nil {
10171024
return big.NewInt(0), err
10181025
}
@@ -1030,7 +1037,7 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (*b
10301037
return total, nil
10311038
}
10321039

1033-
func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.RicardianContract, listings map[string]*pb.Listing) (*big.Int, error) {
1040+
func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.RicardianContract, listings map[string]*repo.Listing) (*big.Int, error) {
10341041
type itemShipping struct {
10351042
primary *big.Int
10361043
secondary *big.Int
@@ -1039,20 +1046,24 @@ func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.Ricardia
10391046
version uint32
10401047
}
10411048
var (
1049+
v5Order, err = repo.ToV5Order(contract.BuyerOrder, n.LookupCurrency)
10421050
is []itemShipping
10431051
shippingTotal *big.Int
10441052
)
1053+
if err != nil {
1054+
return big.NewInt(0), fmt.Errorf("normalizing buyer order: %s", err.Error())
1055+
}
10451056

10461057
// First loop through to validate and filter out non-physical items
1047-
for _, item := range contract.BuyerOrder.Items {
1048-
listing, ok := listings[item.ListingHash]
1058+
for _, item := range v5Order.Items {
1059+
rl, ok := listings[item.ListingHash]
10491060
if !ok {
10501061
continue
10511062
}
10521063

10531064
// Check selected option exists
10541065
shippingOptions := make(map[string]*pb.Listing_ShippingOption)
1055-
for _, so := range listing.ShippingOptions {
1066+
for _, so := range rl.GetProtobuf().ShippingOptions {
10561067
shippingOptions[strings.ToLower(so.Name)] = so
10571068
}
10581069
option, ok := shippingOptions[strings.ToLower(item.ShippingOption.Name)]
@@ -1069,7 +1080,7 @@ func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.Ricardia
10691080
for _, country := range option.Regions {
10701081
regions[country] = true
10711082
}
1072-
_, shipsToMe := regions[contract.BuyerOrder.Shipping.Country]
1083+
_, shipsToMe := regions[v5Order.Shipping.Country]
10731084
_, shipsToAll := regions[pb.CountryCode_ALL]
10741085
if !shipsToMe && !shipsToAll {
10751086
return big.NewInt(0), errors.New("listing does ship to selected country")
@@ -1089,22 +1100,22 @@ func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.Ricardia
10891100
if !ok {
10901101
return big.NewInt(0), errors.New("shipping service not found in listing")
10911102
}
1092-
servicePrice, err := repo.NewCurrencyValueFromProtobuf(service.BigPrice, listing.Item.PriceCurrency)
1103+
servicePrice, err := repo.NewCurrencyValueFromProtobuf(service.BigPrice, rl.GetProtobuf().Item.PriceCurrency)
10931104
if err != nil {
10941105
return big.NewInt(0), fmt.Errorf("parsing service price (%v): %s", service.Name, err.Error())
10951106
}
1096-
convertedShippingPrice, err := servicePrice.ConvertUsingProtobufDef(contract.BuyerOrder.Payment.AmountCurrency, cc)
1107+
convertedShippingPrice, _, err := servicePrice.ConvertUsingProtobufDef(v5Order.Payment.AmountCurrency, cc)
10971108
if err != nil {
10981109
return big.NewInt(0), fmt.Errorf("converting service price (%s): %s", service.Name, err.Error())
10991110
}
11001111

1101-
auxServicePrice, err := repo.NewCurrencyValueFromProtobuf(service.BigAdditionalItemPrice, listing.Item.PriceCurrency)
1112+
auxServicePrice, err := repo.NewCurrencyValueFromProtobuf(service.BigAdditionalItemPrice, rl.GetProtobuf().Item.PriceCurrency)
11021113
if err != nil {
11031114
return big.NewInt(0), fmt.Errorf("parsing aux service price (%v): %s", service.Name, err.Error())
11041115
}
11051116
var convertedAuxPrice = repo.NewCurrencyValueFromBigInt(big.NewInt(0), convertedShippingPrice.Currency)
11061117
if auxServicePrice.IsPositive() {
1107-
finalAux, err := auxServicePrice.ConvertUsingProtobufDef(contract.BuyerOrder.Payment.AmountCurrency, cc)
1118+
finalAux, _, err := auxServicePrice.ConvertUsingProtobufDef(v5Order.Payment.AmountCurrency, cc)
11081119
if err != nil {
11091120
return big.NewInt(0), fmt.Errorf("converting aux service price (%s): %s", service.Name, err.Error())
11101121
}
@@ -1113,19 +1124,19 @@ func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.Ricardia
11131124

11141125
// Calculate tax percentage
11151126
var shippingTaxPercentage float32
1116-
for _, tax := range listing.Taxes {
1127+
for _, tax := range rl.GetProtobuf().Taxes {
11171128
regions := make(map[pb.CountryCode]bool)
11181129
for _, taxRegion := range tax.TaxRegions {
11191130
regions[taxRegion] = true
11201131
}
1121-
_, ok := regions[contract.BuyerOrder.Shipping.Country]
1132+
_, ok := regions[v5Order.Shipping.Country]
11221133
if ok && tax.TaxShipping {
11231134
shippingTaxPercentage = tax.Percentage / 100
11241135
}
11251136
}
11261137

11271138
var qty uint64
1128-
if q := quantityForItem(listing.Metadata.Version, item); q.IsUint64() {
1139+
if q := quantityForItem(rl.GetVersion(), item); q.IsUint64() {
11291140
qty = q.Uint64()
11301141
} else {
11311142
orderID, _ := n.CalcOrderID(contract.BuyerOrder)
@@ -1136,7 +1147,7 @@ func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.Ricardia
11361147
secondary: convertedAuxPrice.AmountBigInt(),
11371148
quantity: qty,
11381149
shippingTaxPercentage: shippingTaxPercentage,
1139-
version: listing.Metadata.Version,
1150+
version: rl.GetVersion(),
11401151
})
11411152
}
11421153

0 commit comments

Comments
 (0)