Skip to content

Commit 1e6eb9b

Browse files
committed
feat: Add support for manual orders
Checkpoint
1 parent 3f82d00 commit 1e6eb9b

File tree

9 files changed

+588
-89
lines changed

9 files changed

+588
-89
lines changed

external/autofill/autofill.go

Lines changed: 8 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,47 @@
11
package autofill
22

33
import (
4-
"fmt"
5-
"reflect"
6-
"strconv"
74
"strings"
85

9-
"github.com/brianvoe/gofakeit/v6"
6+
"github.com/elasticpath/epcc-cli/external/faker"
107
"github.com/elasticpath/epcc-cli/external/resources"
11-
log "github.com/sirupsen/logrus"
128
)
139

14-
var faker = gofakeit.New(0)
15-
16-
var zeroValue = reflect.Value{}
17-
1810
func GetAutoFillQueryParameters(resourceName string, qps []resources.QueryParameter) []string {
1911
args := make([]string, 0)
2012

2113
for _, v := range qps {
2214
key := v.Name
2315
autoFill := v.AutoFill
24-
args = processAutoFill(resourceName, autoFill, args, key, key)
16+
args = processAutoFill(autoFill, args, key)
2517
}
2618

2719
return args
2820
}
21+
2922
func GetJsonArrayForResource(r *resources.Resource) []string {
3023

3124
args := make([]string, 0)
3225

33-
for attributeName, data := range r.Attributes {
26+
for _, data := range r.Attributes {
3427
key := data.Key
3528
key = strings.Replace(key, "data[n]", "data[0]", 1)
3629
autofill := data.AutoFill
3730

38-
args = processAutoFill(r.SingularName, autofill, args, key, attributeName)
31+
args = processAutoFill(autofill, args, key)
3932

4033
}
4134
return args
4235

4336
}
4437

45-
func processAutoFill(resourceName string, autofill string, args []string, key string, attributeName string) []string {
38+
func processAutoFill(autofill string, args []string, key string) []string {
4639
if strings.HasPrefix(autofill, "FUNC:") {
4740

48-
v := reflect.ValueOf(faker)
4941
methodName := strings.Trim(autofill[5:], " ")
5042

51-
var rejectZero = false
52-
if strings.HasPrefix(methodName, "NonZero") {
53-
methodName = methodName[7:]
54-
rejectZero = true
55-
}
56-
57-
method := v.MethodByName(methodName)
58-
if method.IsValid() {
59-
result := method.Call([]reflect.Value{})
60-
if len(result) == 1 {
61-
62-
var arg string
63-
64-
switch {
65-
case result[0].CanUint():
66-
for true {
67-
v := result[0].Uint()
68-
if v == 0 && rejectZero {
69-
result = method.Call([]reflect.Value{})
70-
continue
71-
}
72-
arg = strconv.FormatUint(v, 10)
73-
break
74-
}
75-
76-
case result[0].CanInt():
77-
for true {
78-
v := result[0].Int()
79-
if v == 0 && rejectZero {
80-
result = method.Call([]reflect.Value{})
81-
continue
82-
}
83-
arg = strconv.FormatInt(v, 10)
84-
break
85-
}
86-
default:
87-
arg = result[0].String()
88-
89-
if _, err := strconv.Atoi(arg); err == nil {
90-
// If we get an integer value back, lets just quote it.
91-
arg = fmt.Sprintf("\"%s\"", arg)
92-
}
93-
}
94-
95-
args = append(args, key, arg)
96-
} else {
97-
log.Warnf("Got unexpected number of results from calling %s -> %d", methodName, len(result))
98-
}
99-
100-
} else {
101-
log.Warnf("Could not find autofill method %s for attribute %s on resource %s", methodName, attributeName, resourceName)
102-
}
43+
v := faker.CallFakeFunc(methodName)
44+
args = append(args, key, v)
10345

10446
} else if strings.HasPrefix(autofill, "VALUE:") {
10547
args = append(args, key, strings.Trim(autofill[6:], " "))

external/completion/completion_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,35 @@ func TestCompleteAttributeKeyWithWhenAndSatisfiedExistingValuesReturnsSatisfiedC
821821
require.Len(t, completions, 9)
822822
}
823823

824+
// This test might be redundant but regex was broken for this resource at a time
825+
func TestCompleteAttributeKeyWithEmptyExistingValuesReturnsAllIncludingRegex(t *testing.T) {
826+
// Fixture Setup
827+
toComplete := ""
828+
manualOrder := resources.MustGetResourceByName("manual-order")
829+
request := Request{
830+
Type: CompleteAttributeKey,
831+
Verb: Create,
832+
ToComplete: toComplete,
833+
Resource: manualOrder,
834+
Attributes: map[string]string{
835+
"meta.display_price.with_tax.currency": "USD",
836+
"meta.display_price.balance_owing.formatted": "$10.00",
837+
},
838+
}
839+
840+
// Exercise SUT
841+
completions, compDir := Complete(request)
842+
843+
// Verify Results
844+
require.Equal(t, compDir, cobra.ShellCompDirectiveNoFileComp)
845+
846+
require.Contains(t, completions, "meta.display_price.with_tax.amount")
847+
require.Contains(t, completions, "meta.display_price.balance_owing.currency")
848+
require.NotContains(t, completions, "meta.display_price.with_tax.currency")
849+
require.NotContains(t, completions, "meta.display_price.balance_owing.formatted")
850+
require.Contains(t, completions, "meta.display_price.paid")
851+
}
852+
824853
func TestCompleteAttributeKeyWithWhenSkippingWhen(t *testing.T) {
825854
// Fixture Setup
826855
toComplete := ""

external/faker/faker.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package faker
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"strconv"
7+
"strings"
8+
9+
"github.com/brianvoe/gofakeit/v6"
10+
log "github.com/sirupsen/logrus"
11+
)
12+
13+
var faker = gofakeit.New(1)
14+
15+
func Seed(n int64) {
16+
faker = gofakeit.New(n)
17+
}
18+
19+
func CallFakeFunc(methodName string) string {
20+
21+
var arg string
22+
v := reflect.ValueOf(faker)
23+
24+
var rejectZero = false
25+
if strings.HasPrefix(methodName, "NonZero") {
26+
methodName = methodName[7:]
27+
rejectZero = true
28+
}
29+
30+
method := v.MethodByName(methodName)
31+
if method.IsValid() {
32+
result := method.Call([]reflect.Value{})
33+
if len(result) == 1 {
34+
35+
switch {
36+
case result[0].CanUint():
37+
for {
38+
v := result[0].Uint()
39+
if v == 0 && rejectZero {
40+
result = method.Call([]reflect.Value{})
41+
continue
42+
}
43+
arg = strconv.FormatUint(v, 10)
44+
break
45+
}
46+
47+
case result[0].CanInt():
48+
for {
49+
v := result[0].Int()
50+
if v == 0 && rejectZero {
51+
result = method.Call([]reflect.Value{})
52+
continue
53+
}
54+
arg = strconv.FormatInt(v, 10)
55+
break
56+
}
57+
default:
58+
arg = result[0].String()
59+
60+
if _, err := strconv.Atoi(arg); err == nil {
61+
// If we get an integer value back, lets just quote it.
62+
arg = fmt.Sprintf("\"%s\"", arg)
63+
}
64+
}
65+
66+
} else {
67+
log.Warnf("Got unexpected number of results from calling %s -> %d", methodName, len(result))
68+
}
69+
70+
} else {
71+
log.Warnf("Could not find autofill method %s", methodName)
72+
}
73+
74+
return arg
75+
}

external/resources/yaml/carts-and-orders.yaml

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,162 @@ order-transaction-refund:
387387
docs: "https://elasticpath.dev/docs/carts-orders/refund-a-transaction"
388388
url: "/v2/orders/{orders}/transactions/{order_transactions}/refund"
389389
openapi-operation-id: refundATransaction
390+
391+
manual-orders:
392+
singular-name: "manual-order"
393+
json-api-type: order
394+
json-api-format: legacy
395+
docs: "https://elasticpath.dev/docs/api/carts/orders"
396+
create-entity:
397+
docs: "https://elasticpath.dev/docs/api/carts/orders"
398+
url: "/v2/orders"
399+
attributes:
400+
id:
401+
type: STRING
402+
usage: "Optional custom order ID. If not provided, a UUID will be generated."
403+
status:
404+
type: ENUM:incomplete,processing,cancelled,complete
405+
usage: "The status of the order."
406+
payment:
407+
type: ENUM:paid,unpaid,refunded,partially_authorized,partially_paid
408+
usage: "The payment status of the order."
409+
shipping:
410+
type: ENUM:fulfilled,unfulfilled
411+
usage: "The shipping status of the order."
412+
anonymized:
413+
type: BOOL
414+
usage: "Whether the order should be anonymized."
415+
account.id:
416+
type: RESOURCE_ID:account
417+
usage: "The unique identifier of the account."
418+
account.member_id:
419+
type: RESOURCE_ID:account-member
420+
usage: "The unique identifier of the account member."
421+
contact.name:
422+
type: STRING
423+
usage: "Contact name for the order."
424+
contact.email:
425+
type: STRING
426+
usage: "Contact email for the order."
427+
customer.id:
428+
type: RESOURCE_ID:customer
429+
usage: "The unique identifier of the customer."
430+
autofill: FUNC:UUID
431+
customer.email:
432+
type: STRING
433+
usage: "Customer email address."
434+
autofill: FUNC:Email
435+
customer.name:
436+
type: STRING
437+
usage: "Customer name."
438+
autofill: FUNC:Name
439+
shipping_address.first_name:
440+
type: STRING
441+
autofill: FUNC:FirstName
442+
shipping_address.last_name:
443+
type: STRING
444+
autofill: FUNC:LastName
445+
shipping_address.company_name:
446+
type: STRING
447+
autofill: FUNC:Company
448+
shipping_address.line_1:
449+
type: STRING
450+
autofill: FUNC:Street
451+
shipping_address.line_2:
452+
type: STRING
453+
shipping_address.city:
454+
type: STRING
455+
autofill: FUNC:City
456+
shipping_address.county:
457+
type: STRING
458+
shipping_address.region:
459+
type: STRING
460+
autofill: FUNC:State
461+
shipping_address.postcode:
462+
type: STRING
463+
autofill: FUNC:Zip
464+
shipping_address.country:
465+
type: STRING
466+
autofill: FUNC:Country
467+
billing_address.first_name:
468+
type: STRING
469+
autofill: FUNC:FirstName
470+
billing_address.last_name:
471+
type: STRING
472+
autofill: FUNC:LastName
473+
billing_address.company_name:
474+
type: STRING
475+
autofill: FUNC:Company
476+
billing_address.line_1:
477+
type: STRING
478+
autofill: FUNC:Street
479+
billing_address.line_2:
480+
type: STRING
481+
billing_address.city:
482+
type: STRING
483+
autofill: FUNC:City
484+
billing_address.county:
485+
type: STRING
486+
billing_address.region:
487+
type: STRING
488+
autofill: FUNC:State
489+
billing_address.postcode:
490+
type: STRING
491+
autofill: FUNC:Zip
492+
billing_address.country:
493+
type: STRING
494+
autofill: FUNC:Country
495+
^meta\.display_price\.(with_tax|without_tax|tax|discount|balance_owing|paid|authorized|without_discount|shipping|shipping_discount)\.amount$:
496+
type: INT
497+
usage: "The amount of the order specified in currency subunits"
498+
^meta\.display_price\.(with_tax|without_tax|tax|discount|balance_owing|paid|authorized|without_discount|shipping|shipping_discount)\.currency$:
499+
type: CURRENCY
500+
usage: "The currency"
501+
^meta\.display_price\.(with_tax|without_tax|tax|discount|balance_owing|paid|authorized|without_discount|shipping|shipping_discount)\.formatted$:
502+
type: STRING
503+
usage: "The amount of the order specified as a formatted string"
504+
included.items[n].id:
505+
type: STRING
506+
usage: "The unique identifier of the item."
507+
included.items[n].type:
508+
type: CONST:order_item
509+
included.items[n].quantity:
510+
type: INT
511+
included.items[n].location:
512+
type: STRING
513+
included.items[n].product_id:
514+
type: RESOURCE_ID:pcm-product
515+
included.items[n].subscription_offering_id:
516+
type: RESOURCE_ID:subscription-offerings
517+
included.items[n].name:
518+
type: RESOURCE:STRING
519+
included.items[n].sku:
520+
type: STRING
521+
^included\.items[n]\.(unit_price|value)\.amount$:
522+
type: INT
523+
usage: "An amount in currency subunits if applicable (e.g., $100.00 would be 10000)"
524+
^included\.items[n]\.(unit_price|value)\.currency$:
525+
type: CURRENCY
526+
^included\.items[n]\.(unit_price|value)\.include_tax$:
527+
type: BOOL
528+
^included\.items[n]\.meta\.display_price\.(with_tax|without_tax|tax|discount_without_discount)\.(unit|value)\.amount$:
529+
type: INT
530+
usage: "An amount in currency subunits if applicable (e.g., $100.00 would be 10000)"
531+
^included\.items[n]\.meta\.display_price\.(with_tax|without_tax|tax|discount_without_discount)\.(unit|value)\.currency$:
532+
type: CURRENCY
533+
^included\.items[n]\.meta\.display_price\.(with_tax|without_tax|tax|discount_without_discount)\.(unit|value)\.formatted$:
534+
usage: "A formatted amount e.g., $100.00"
535+
type: STRING
536+
included.items[n].meta.timestamps.created_at:
537+
type: STRING
538+
included.items[n].meta.timestamps.updated_at:
539+
type: STRING
540+
541+
542+
543+
544+
545+
546+
547+
548+

0 commit comments

Comments
 (0)