@@ -774,21 +774,21 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (ui
774774 }
775775
776776 // Add in shipping costs
777- type combinedShipping struct {
778- quantity int
779- price uint64
780- add bool
781- modifier uint64
777+ type itemShipping struct {
778+ primary uint64
779+ secondary uint64
780+ quantity uint32
781+ shippingTaxPercentage float32
782+ version uint32
782783 }
783- var combinedOptions []combinedShipping
784+ var is []itemShipping
784785
785- var shippingTotal uint64
786+ // First loop through to validate and filter out non-physical items
786787 for _ , item := range contract .BuyerOrder .Items {
787788 listing , ok := physicalGoods [item .ListingHash ]
788789 if ! ok { // Not physical good no need to calculate shipping
789790 continue
790791 }
791- var itemShipping uint64
792792 // Check selected option exists
793793 shippingOptions := make (map [string ]* pb.Listing_ShippingOption )
794794 for _ , so := range listing .ShippingOptions {
@@ -827,11 +827,17 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (ui
827827 if err != nil {
828828 return 0 , err
829829 }
830- shippingPrice := uint64 (item .Quantity ) * shippingSatoshi
831- itemShipping += shippingPrice
832- shippingTaxPercentage := float32 (0 )
830+
831+ var secondarySatoshi uint64
832+ if service .AdditionalItemPrice > 0 {
833+ secondarySatoshi , err = n .getPriceInSatoshi (listing .Metadata .PricingCurrency , service .AdditionalItemPrice )
834+ if err != nil {
835+ return 0 , err
836+ }
837+ }
833838
834839 // Calculate tax percentage
840+ var shippingTaxPercentage float32
835841 for _ , tax := range listing .Taxes {
836842 regions := make (map [pb.CountryCode ]bool )
837843 for _ , taxRegion := range tax .TaxRegions {
@@ -843,98 +849,41 @@ func (n *OpenBazaarNode) CalculateOrderTotal(contract *pb.RicardianContract) (ui
843849 }
844850 }
845851
846- // Apply shipping rules
847- if option .ShippingRules != nil {
848- for _ , rule := range option .ShippingRules .Rules {
849- switch option .ShippingRules .RuleType {
850- case pb .Listing_ShippingOption_ShippingRules_QUANTITY_DISCOUNT :
851- if item .Quantity >= rule .MinRange && item .Quantity <= rule .MaxRange {
852- rulePrice , err := n .getPriceInSatoshi (listing .Metadata .PricingCurrency , rule .Price )
853- if err != nil {
854- return 0 , err
855- }
856- itemShipping -= rulePrice
857- }
858- case pb .Listing_ShippingOption_ShippingRules_FLAT_FEE_QUANTITY_RANGE :
859- if item .Quantity >= rule .MinRange && item .Quantity <= rule .MaxRange {
860- itemShipping -= shippingPrice
861- rulePrice , err := n .getPriceInSatoshi (listing .Metadata .PricingCurrency , rule .Price )
862- if err != nil {
863- return 0 , err
864- }
865- itemShipping += rulePrice
866- }
867- case pb .Listing_ShippingOption_ShippingRules_FLAT_FEE_WEIGHT_RANGE :
868- weight := listing .Item .Grams * float32 (item .Quantity )
869- if uint32 (weight ) >= rule .MinRange && uint32 (weight ) <= rule .MaxRange {
870- itemShipping -= shippingPrice
871- rulePrice , err := n .getPriceInSatoshi (listing .Metadata .PricingCurrency , rule .Price )
872- if err != nil {
873- return 0 , err
874- }
875- itemShipping += rulePrice
876- }
877- case pb .Listing_ShippingOption_ShippingRules_COMBINED_SHIPPING_ADD :
878- itemShipping -= shippingPrice
879- rulePrice , err := n .getPriceInSatoshi (listing .Metadata .PricingCurrency , rule .Price )
880- rulePrice += uint64 (float32 (rulePrice ) * shippingTaxPercentage )
881- shippingSatoshi += uint64 (float32 (shippingSatoshi ) * shippingTaxPercentage )
882- if err != nil {
883- return 0 , err
884- }
885- cs := combinedShipping {
886- quantity : int (item .Quantity ),
887- price : shippingSatoshi ,
888- add : true ,
889- modifier : rulePrice ,
890- }
891- combinedOptions = append (combinedOptions , cs )
892-
893- case pb .Listing_ShippingOption_ShippingRules_COMBINED_SHIPPING_SUBTRACT :
894- itemShipping -= shippingPrice
895- rulePrice , err := n .getPriceInSatoshi (listing .Metadata .PricingCurrency , rule .Price )
896- rulePrice += uint64 (float32 (rulePrice ) * shippingTaxPercentage )
897- shippingSatoshi += uint64 (float32 (shippingSatoshi ) * shippingTaxPercentage )
898- if err != nil {
899- return 0 , err
900- }
901- cs := combinedShipping {
902- quantity : int (item .Quantity ),
903- price : shippingSatoshi ,
904- add : false ,
905- modifier : rulePrice ,
906- }
907- combinedOptions = append (combinedOptions , cs )
908- }
909- }
910- }
911- // Apply tax
912- itemShipping += uint64 (float32 (itemShipping ) * shippingTaxPercentage )
913- shippingTotal += itemShipping
852+ is = append (is , itemShipping {
853+ primary : shippingSatoshi ,
854+ secondary : secondarySatoshi ,
855+ quantity : item .Quantity ,
856+ shippingTaxPercentage : shippingTaxPercentage ,
857+ version : listing .Metadata .Version ,
858+ })
914859 }
915860
916- // Process combined shipping rules
917- if len (combinedOptions ) > 0 {
918- lowestPrice := int64 (- 1 )
919- for _ , v := range combinedOptions {
920- if int64 (v .price ) < lowestPrice || lowestPrice == - 1 {
921- lowestPrice = int64 (v .price )
861+ var shippingTotal uint64
862+ if len (is ) == 1 {
863+ shippingTotal = (is [0 ].primary * uint64 (((1 + is [0 ].shippingTaxPercentage )* 100 )+ .5 ) / 100 )
864+ if is [0 ].quantity > 1 {
865+ if is [0 ].version == 1 {
866+ shippingTotal += (is [0 ].primary * uint64 (((1 + is [0 ].shippingTaxPercentage )* 100 )+ .5 ) / 100 ) * uint64 ((is [0 ].quantity - 1 ))
867+ } else if is [0 ].version == 2 {
868+ shippingTotal += (is [0 ].secondary * uint64 (((1 + is [0 ].shippingTaxPercentage )* 100 )+ .5 ) / 100 ) * uint64 ((is [0 ].quantity - 1 ))
869+ } else {
870+ return 0 , errors .New ("Unknown listing version" )
922871 }
923872 }
924- shippingTotal += uint64 (lowestPrice )
925- for _ , o := range combinedOptions {
926- modifier := o .modifier
927- modifier *= (uint64 (o .quantity ) - 1 )
928- if o .add {
929- shippingTotal += modifier
930- } else {
931- shippingTotal -= modifier
873+ } else if len (is ) > 1 {
874+ var highest uint64
875+ var i int
876+ for x , s := range is {
877+ if s .primary > highest {
878+ highest = s .primary
879+ i = x
932880 }
881+ shippingTotal += (s .secondary * uint64 (((1 + s .shippingTaxPercentage )* 100 )+ .5 ) / 100 ) * uint64 (s .quantity )
933882 }
883+ shippingTotal -= (is [i ].primary * uint64 (((1 + is [i ].shippingTaxPercentage )* 100 )+ .5 ) / 100 )
884+ shippingTotal += (is [i ].secondary * uint64 (((1 + is [i ].shippingTaxPercentage )* 100 )+ .5 ) / 100 )
934885 }
935-
936- total += shippingTotal
937- return total , nil
886+ return total + shippingTotal , nil
938887}
939888
940889func (n * OpenBazaarNode ) getPriceInSatoshi (currencyCode string , amount uint64 ) (uint64 , error ) {
0 commit comments