File size: 8,428 Bytes
cee2387
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package transactions

import (
	"fmt"

	"github.com/openmeterio/openmeter/openmeter/ledger"
)

type TransactionTemplateCode string

const (
	TemplateCodeIssueCustomerReceivable                     TransactionTemplateCode = "customer.receivable.issue"
	TemplateCodeAuthorizeCustomerReceivablePayment          TransactionTemplateCode = "customer.receivable.payment.authorize"
	TemplateCodeSettleCustomerReceivableFromPayment         TransactionTemplateCode = "customer.receivable.payment.settle"
	TemplateCodeAttributeCustomerAdvanceReceivableCostBasis TransactionTemplateCode = "customer.receivable.advance.attribute"
	TemplateCodeCoverCustomerReceivable                     TransactionTemplateCode = "customer.receivable.cover"
	TemplateCodeTransferCustomerFBOToAccrued                TransactionTemplateCode = "customer.fbo.collect"
	TemplateCodeTransferCustomerFBOAdvanceToAccrued         TransactionTemplateCode = "customer.fbo.advance.collect"
	TemplateCodeTransferCustomerReceivableToAccrued         TransactionTemplateCode = "customer.receivable.collect"
	TemplateCodeTranslateCustomerAccruedCostBasis           TransactionTemplateCode = "customer.accrued.cost_basis.translate"
	TemplateCodeRecognizeEarningsFromAttributableAccrued    TransactionTemplateCode = "customer.accrued.earnings.recognize"
	TemplateCodeConvertCurrency                             TransactionTemplateCode = "customer.fbo.currency.convert"
	TemplateCodePlanCustomerFBOBreakage                     TransactionTemplateCode = "customer.fbo.breakage.plan"
	TemplateCodeReleaseCustomerFBOBreakage                  TransactionTemplateCode = "customer.fbo.breakage.release"
	TemplateCodeReopenCustomerFBOBreakage                   TransactionTemplateCode = "customer.fbo.breakage.reopen"
)

const (
	legacyTemplateNameIssueCustomerReceivable                     = "IssueCustomerReceivableTemplate"
	legacyTemplateNameFundCustomerReceivable                      = "FundCustomerReceivableTemplate"
	legacyTemplateNameSettleCustomerReceivablePayment             = "SettleCustomerReceivablePaymentTemplate"
	legacyTemplateNameAuthorizeCustomerReceivablePayment          = "AuthorizeCustomerReceivablePaymentTemplate"
	legacyTemplateNameSettleCustomerReceivableFromPayment         = "SettleCustomerReceivableFromPaymentTemplate"
	legacyTemplateNameAttributeCustomerAdvanceReceivableCostBasis = "AttributeCustomerAdvanceReceivableCostBasisTemplate"
	legacyTemplateNameCoverCustomerReceivable                     = "CoverCustomerReceivableTemplate"
	legacyTemplateNameTransferCustomerFBOToAccrued                = "TransferCustomerFBOToAccruedTemplate"
	legacyTemplateNameTransferCustomerFBOAdvanceToAccrued         = "TransferCustomerFBOAdvanceToAccruedTemplate"
	legacyTemplateNameTransferCustomerReceivableToAccrued         = "TransferCustomerReceivableToAccruedTemplate"
	legacyTemplateNameTranslateCustomerAccruedCostBasis           = "TranslateCustomerAccruedCostBasisTemplate"
	legacyTemplateNameRecognizeEarningsFromAttributableAccrued    = "RecognizeEarningsFromAttributableAccruedTemplate"
	legacyTemplateNameConvertCurrency                             = "ConvertCurrencyTemplate"
	legacyTemplateNamePlanCustomerFBOBreakage                     = "PlanCustomerFBOBreakageTemplate"
	legacyTemplateNameReleaseCustomerFBOBreakage                  = "ReleaseCustomerFBOBreakageTemplate"
	legacyTemplateNameReopenCustomerFBOBreakage                   = "ReopenCustomerFBOBreakageTemplate"
)

var transactionTemplatesByLegacyName = map[string]TransactionTemplate{
	legacyTemplateNameIssueCustomerReceivable:                     IssueCustomerReceivableTemplate{},
	legacyTemplateNameFundCustomerReceivable:                      legacyFundCustomerReceivableTemplate{},
	legacyTemplateNameSettleCustomerReceivablePayment:             legacySettleCustomerReceivablePaymentTemplate{},
	legacyTemplateNameAuthorizeCustomerReceivablePayment:          AuthorizeCustomerReceivablePaymentTemplate{},
	legacyTemplateNameSettleCustomerReceivableFromPayment:         SettleCustomerReceivableFromPaymentTemplate{},
	legacyTemplateNameAttributeCustomerAdvanceReceivableCostBasis: AttributeCustomerAdvanceReceivableCostBasisTemplate{},
	legacyTemplateNameCoverCustomerReceivable:                     CoverCustomerReceivableTemplate{},
	legacyTemplateNameTransferCustomerFBOToAccrued:                TransferCustomerFBOToAccruedTemplate{},
	legacyTemplateNameTransferCustomerFBOAdvanceToAccrued:         TransferCustomerFBOAdvanceToAccruedTemplate{},
	legacyTemplateNameTransferCustomerReceivableToAccrued:         TransferCustomerReceivableToAccruedTemplate{},
	legacyTemplateNameTranslateCustomerAccruedCostBasis:           TranslateCustomerAccruedCostBasisTemplate{},
	legacyTemplateNameRecognizeEarningsFromAttributableAccrued:    RecognizeEarningsFromAttributableAccruedTemplate{},
	legacyTemplateNameConvertCurrency:                             ConvertCurrencyTemplate{},
	legacyTemplateNamePlanCustomerFBOBreakage:                     PlanCustomerFBOBreakageTemplate{},
	legacyTemplateNameReleaseCustomerFBOBreakage:                  ReleaseCustomerFBOBreakageTemplate{},
	legacyTemplateNameReopenCustomerFBOBreakage:                   ReopenCustomerFBOBreakageTemplate{},
}

var transactionTemplatesByCode = map[TransactionTemplateCode]TransactionTemplate{
	IssueCustomerReceivableTemplate{}.code():                     IssueCustomerReceivableTemplate{},
	AuthorizeCustomerReceivablePaymentTemplate{}.code():          AuthorizeCustomerReceivablePaymentTemplate{},
	SettleCustomerReceivableFromPaymentTemplate{}.code():         SettleCustomerReceivableFromPaymentTemplate{},
	AttributeCustomerAdvanceReceivableCostBasisTemplate{}.code(): AttributeCustomerAdvanceReceivableCostBasisTemplate{},
	CoverCustomerReceivableTemplate{}.code():                     CoverCustomerReceivableTemplate{},
	TransferCustomerFBOToAccruedTemplate{}.code():                TransferCustomerFBOToAccruedTemplate{},
	TransferCustomerFBOAdvanceToAccruedTemplate{}.code():         TransferCustomerFBOAdvanceToAccruedTemplate{},
	TransferCustomerReceivableToAccruedTemplate{}.code():         TransferCustomerReceivableToAccruedTemplate{},
	TranslateCustomerAccruedCostBasisTemplate{}.code():           TranslateCustomerAccruedCostBasisTemplate{},
	RecognizeEarningsFromAttributableAccruedTemplate{}.code():    RecognizeEarningsFromAttributableAccruedTemplate{},
	ConvertCurrencyTemplate{}.code():                             ConvertCurrencyTemplate{},
	PlanCustomerFBOBreakageTemplate{}.code():                     PlanCustomerFBOBreakageTemplate{},
	ReleaseCustomerFBOBreakageTemplate{}.code():                  ReleaseCustomerFBOBreakageTemplate{},
	ReopenCustomerFBOBreakageTemplate{}.code():                   ReopenCustomerFBOBreakageTemplate{},
}

func templateCode(template TransactionTemplate) (TransactionTemplateCode, error) {
	code := template.code()
	if code == "" {
		return "", fmt.Errorf("unknown transaction template code for %T", template)
	}

	return code, nil
}

func transactionTemplateByCode(code string) (TransactionTemplate, error) {
	template, ok := transactionTemplatesByCode[TransactionTemplateCode(code)]
	if !ok {
		return nil, fmt.Errorf("unknown correction template code %q", code)
	}

	return template, nil
}

func transactionTemplateByLegacyName(name string) (TransactionTemplate, error) {
	template, ok := transactionTemplatesByLegacyName[name]
	if !ok {
		return nil, fmt.Errorf("unknown correction template name %q", name)
	}

	return template, nil
}

func TemplateCode(template TransactionTemplate) string {
	code, err := templateCode(template)
	if err != nil {
		panic(err)
	}

	return string(code)
}

func annotateTemplateTransaction(input ledger.TransactionInput, template TransactionTemplate, direction ledger.TransactionDirection) (ledger.TransactionInput, error) {
	code, err := templateCode(template)
	if err != nil {
		return nil, err
	}

	return WithAnnotations(input, ledger.TransactionAnnotations(string(code), direction)), nil
}

func appendResolvedTemplateTransaction(
	inputs []ledger.TransactionInput,
	input ledger.TransactionInput,
	template TransactionTemplate,
	direction ledger.TransactionDirection,
) ([]ledger.TransactionInput, error) {
	if input == nil {
		return inputs, nil
	}

	annotated, err := annotateTemplateTransaction(input, template, direction)
	if err != nil {
		return nil, err
	}

	return append(inputs, annotated), nil
}