@@ -896,7 +896,7 @@ func (n *OpenBazaarNode) CheckoutBreakdown(data *repo.PurchaseData) (repo.Checko
896
896
return emptyCheckoutBreakdown , err
897
897
}
898
898
899
- totalSurcharge , err := GetTotalSurchargeAmount (nrl , firstItem .Options )
899
+ itemSurcharge , err := GetItemSurchargeAmount (nrl , firstItem .Options )
900
900
if err != nil {
901
901
return emptyCheckoutBreakdown , err
902
902
}
@@ -932,8 +932,9 @@ func (n *OpenBazaarNode) CheckoutBreakdown(data *repo.PurchaseData) (repo.Checko
932
932
if err != nil {
933
933
return emptyCheckoutBreakdown , err
934
934
}
935
+ totalSurcharge := new (big.Int ).Mul (itemSurcharge , totalQuantity )
935
936
cv := & repo.CurrencyValue {
936
- Amount : totalSurcharge . Add (totalSurcharge , itemOriginAmt .Amount ),
937
+ Amount : new (big. Int ). Add (itemSurcharge , itemOriginAmt .Amount ),
937
938
Currency : listingCurDef ,
938
939
}
939
940
couponDiscount , err := GetTotalCouponCodeDiscount (nrl , firstItem .CouponCodes , cv )
@@ -966,28 +967,51 @@ func (n *OpenBazaarNode) CheckoutBreakdown(data *repo.PurchaseData) (repo.Checko
966
967
967
968
shippingTotal := new (big.Int ).SetInt64 (0 )
968
969
if isPhysicalGood {
969
-
970
- shippingTotal , err = n .calculateShippingTotalForListings (contract , physicalGoods )
970
+ shippingTotal , err = getPretaxShippingCost (v5Order , nrl )
971
971
if err != nil {
972
972
return emptyCheckoutBreakdown , err
973
973
}
974
974
}
975
+ // Convert to final currency
976
+ shippingCurrencyValue := repo .NewCurrencyValueFromBigInt (shippingTotal , listingCurDef )
977
+ finalShippingTotal , _ , err := shippingCurrencyValue .ConvertUsingProtobufDef (v5Order .Payment .AmountCurrency , cc )
978
+ if err != nil {
979
+ return emptyCheckoutBreakdown , err
980
+ }
975
981
976
982
// Taxes
977
983
taxesTotal := new (big.Int ).SetInt64 (0 )
978
984
for _ , tax := range nrl .GetProtobuf ().Taxes {
979
985
for _ , taxRegion := range tax .TaxRegions {
980
986
if contract .BuyerOrder .Shipping .Country == taxRegion {
981
987
factor := toHundredths (tax .Percentage )
982
- taxes , _ := new (big.Float ).Mul (new (big.Float ).SetInt (itemOriginAmt .Amount ), factor ).Int (nil )
988
+
989
+ var taxes * big.Int
990
+ amountToTax := new (big.Int ).SetInt64 (0 )
991
+
992
+ totalBasePrice := new (big.Int ).Mul (itemOriginAmt .Amount , totalQuantity )
993
+ amountToTax .Add (totalBasePrice , totalSurcharge )
994
+ amountToTax .Sub (amountToTax , couponDiscount )
995
+
996
+ if tax .TaxShipping {
997
+ amountToTax .Add (amountToTax , shippingTotal )
998
+ }
999
+
1000
+ taxes , _ = new (big.Float ).Mul (new (big.Float ).SetInt (amountToTax ), factor ).Int (nil )
983
1001
taxesTotal = new (big.Int ).Add (taxesTotal , taxes )
1002
+
984
1003
break
985
1004
}
986
1005
}
987
1006
}
1007
+ taxesCurrencyValue := repo .NewCurrencyValueFromBigInt (taxesTotal , listingCurDef )
1008
+ finalTaxesTotal , _ , err := taxesCurrencyValue .ConvertUsingProtobufDef (v5Order .Payment .AmountCurrency , cc )
1009
+ if err != nil {
1010
+ return emptyCheckoutBreakdown , err
1011
+ }
988
1012
989
- checkoutBreakdown .Tax = taxesTotal .String ()
990
- checkoutBreakdown .ShippingPrice = shippingTotal .String ()
1013
+ checkoutBreakdown .Tax = finalTaxesTotal . Amount .String ()
1014
+ checkoutBreakdown .ShippingPrice = finalShippingTotal . Amount .String ()
991
1015
checkoutBreakdown .Coupon = finalCouponDiscount .Amount .String ()
992
1016
checkoutBreakdown .OptionSurcharge = finalOptionSurcharge .Amount .String ()
993
1017
checkoutBreakdown .BasePrice = finalBasePrice .Amount .String ()
@@ -997,6 +1021,60 @@ func (n *OpenBazaarNode) CheckoutBreakdown(data *repo.PurchaseData) (repo.Checko
997
1021
return checkoutBreakdown , nil
998
1022
}
999
1023
1024
+ func getPretaxShippingCost (v5Order * pb.Order , nrl * repo.Listing ) (* big.Int , error ) {
1025
+ pretaxShippingCost := new (big.Int ).SetInt64 (0 )
1026
+
1027
+ for _ , item := range v5Order .Items {
1028
+ //shippingOption := item.ShippingOption
1029
+
1030
+ itemQuantity , ok := new (big.Int ).SetString (item .BigQuantity , 10 )
1031
+ if ! ok {
1032
+ return new (big.Int ).SetInt64 (0 ), errors .New ("bad bigQuantity" )
1033
+ }
1034
+ listingShippingOptions , err := nrl .GetShippingOptions ()
1035
+ if err != nil {
1036
+ return new (big.Int ).SetInt64 (0 ), err
1037
+ }
1038
+
1039
+ for _ , listingShippingOption := range listingShippingOptions {
1040
+ if inShippingRegions (v5Order .Shipping .Country , listingShippingOption .Regions ) {
1041
+ for _ , listingService := range listingShippingOption .Services {
1042
+ if item .ShippingOption .Service == listingService .Name {
1043
+ servicePrice , _ := new (big.Int ).SetString (listingService .BigPrice , 10 )
1044
+ if err != nil {
1045
+ return new (big.Int ).SetInt64 (0 ), err
1046
+ }
1047
+ additionalItemPrice , _ := new (big.Int ).SetString (listingService .BigAdditionalItemPrice , 10 )
1048
+ if err != nil {
1049
+ return new (big.Int ).SetInt64 (0 ), err
1050
+ }
1051
+
1052
+ pretaxShippingCost .Add (pretaxShippingCost , servicePrice )
1053
+
1054
+ if itemQuantity .Cmp (new (big.Int ).SetInt64 (1 )) == 1 {
1055
+ // Add additional item price for each quantity over 1
1056
+ additionalCost := new (big.Int ).Mul (additionalItemPrice , itemQuantity )
1057
+ pretaxShippingCost .Add (pretaxShippingCost , additionalCost )
1058
+ }
1059
+
1060
+ }
1061
+ }
1062
+ }
1063
+ }
1064
+ }
1065
+
1066
+ return pretaxShippingCost , nil
1067
+ }
1068
+
1069
+ func inShippingRegions (needle pb.CountryCode , regions []pb.CountryCode ) bool {
1070
+ for _ , region := range regions {
1071
+ if needle == region || region == pb .CountryCode_ALL {
1072
+ return true
1073
+ }
1074
+ }
1075
+ return false
1076
+ }
1077
+
1000
1078
// CancelOfflineOrder - cancel order
1001
1079
func (n * OpenBazaarNode ) CancelOfflineOrder (contract * pb.RicardianContract , records []* wallet.TransactionRecord ) error {
1002
1080
v5Order , err := repo .ToV5Order (contract .BuyerOrder , nil )
@@ -1125,11 +1203,11 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (*b
1125
1203
}
1126
1204
1127
1205
// apply surcharges
1128
- totalSurcharge , err := GetTotalSurchargeAmount (nrl , item .Options )
1206
+ itemSurcharge , err := GetItemSurchargeAmount (nrl , item .Options )
1129
1207
if err != nil {
1130
1208
return big .NewInt (0 ), err
1131
1209
}
1132
- itemOriginAmt = itemOriginAmt .AddBigInt (totalSurcharge )
1210
+ itemOriginAmt = itemOriginAmt .AddBigInt (itemSurcharge )
1133
1211
1134
1212
// apply coupon discounts
1135
1213
totalDiscount , err := GetTotalCouponCodeDiscount (nrl , item .CouponCodes , itemOriginAmt )
@@ -1207,8 +1285,8 @@ func GetTotalCouponCodeDiscount(nrl *repo.Listing, couponCodes []string, itemAmo
1207
1285
return totalCouponCodeDiscount , nil
1208
1286
}
1209
1287
1210
- func GetTotalSurchargeAmount (nrl * repo.Listing , options []* pb.Order_Item_Option ) (* big.Int , error ) {
1211
- totalSurchargeAmount := big .NewInt (0 )
1288
+ func GetItemSurchargeAmount (nrl * repo.Listing , options []* pb.Order_Item_Option ) (* big.Int , error ) {
1289
+ itemSurchargeAmount := big .NewInt (0 )
1212
1290
1213
1291
selectedSku , err := GetSelectedSku (nrl .GetProtobuf (), options )
1214
1292
if err != nil {
@@ -1223,12 +1301,12 @@ func GetTotalSurchargeAmount(nrl *repo.Listing, options []*pb.Order_Item_Option)
1223
1301
// surcharge may be positive or negative
1224
1302
surcharge , ok := new (big.Int ).SetString (sku .BigSurcharge , 10 )
1225
1303
if ok && surcharge .Cmp (big .NewInt (0 )) != 0 {
1226
- totalSurchargeAmount .Add (totalSurchargeAmount , surcharge )
1304
+ itemSurchargeAmount .Add (itemSurchargeAmount , surcharge )
1227
1305
}
1228
1306
break
1229
1307
}
1230
1308
}
1231
- return totalSurchargeAmount , nil
1309
+ return itemSurchargeAmount , nil
1232
1310
}
1233
1311
func toHundredths (f float32 ) * big.Float {
1234
1312
return new (big.Float ).Mul (big .NewFloat (float64 (f )), big .NewFloat (0.01 ))
@@ -1298,14 +1376,15 @@ func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.Ricardia
1298
1376
continue
1299
1377
}
1300
1378
1301
- // Check selected option exists
1302
- shippingOptions := make (map [string ]* pb.Listing_ShippingOption )
1303
- for _ , so := range rl .GetProtobuf ().ShippingOptions {
1304
- shippingOptions [strings .ToLower (so .Name )] = so
1379
+ // Check if physical good
1380
+ if rl .GetContractType () != pb .Listing_Metadata_PHYSICAL_GOOD .String () {
1381
+ continue
1305
1382
}
1306
- option , ok := shippingOptions [strings .ToLower (item .ShippingOption .Name )]
1307
- if ! ok {
1308
- return big .NewInt (0 ), errors .New ("shipping option not found in listing" )
1383
+
1384
+ // Check selected option exists
1385
+ option , err := getShippingOption (rl , item .ShippingOption .Name )
1386
+ if err != nil {
1387
+ return big .NewInt (0 ), err
1309
1388
}
1310
1389
1311
1390
if option .Type == pb .Listing_ShippingOption_LOCAL_PICKUP {
@@ -1440,6 +1519,18 @@ func (n *OpenBazaarNode) calculateShippingTotalForListings(contract *pb.Ricardia
1440
1519
return shippingTotal , nil
1441
1520
}
1442
1521
1522
+ func getShippingOption (rl * repo.Listing , optionName string ) (* pb.Listing_ShippingOption , error ) {
1523
+ shippingOptions := make (map [string ]* pb.Listing_ShippingOption )
1524
+ for _ , so := range rl .GetProtobuf ().ShippingOptions {
1525
+ shippingOptions [strings .ToLower (so .Name )] = so
1526
+ }
1527
+ option , ok := shippingOptions [strings .ToLower (optionName )]
1528
+ if ! ok {
1529
+ return nil , errors .New ("shipping option not found in listing" )
1530
+ }
1531
+ return option , nil
1532
+ }
1533
+
1443
1534
func verifySignaturesOnOrder (contract * pb.RicardianContract ) error {
1444
1535
if err := verifyMessageSignature (
1445
1536
contract .BuyerOrder ,
0 commit comments