more services
parent
e777b6a6cc
commit
50901b818f
|
@ -8,6 +8,44 @@ import (
|
||||||
"code.tnxs.net/taxnexus/lib/api/geo/geo_models"
|
"code.tnxs.net/taxnexus/lib/api/geo/geo_models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetDefaultDeliveryAddress is an account helper function
|
||||||
|
func GetDefaultDeliveryAddress(obj *Account, principal *User) (*Address, error) {
|
||||||
|
var deliveryAddress Address
|
||||||
|
theContact, err := GetContactByID(obj.DefaultDeliveryContactID, principal)
|
||||||
|
if err != nil {
|
||||||
|
sugar.Errorf("ops.getDefaultAddress: 💣 ⛔ theAccount.Defaultdeliverycontactid invalid %w", err)
|
||||||
|
if obj.ShippingAddress == nil {
|
||||||
|
if obj.BillingAddress == nil {
|
||||||
|
return nil, fmt.Errorf("ops.GetDefaultDeliveryAddress: 💣 ⛔ can't find any valid addresses")
|
||||||
|
}
|
||||||
|
deliveryAddress = *obj.BillingAddress
|
||||||
|
} else {
|
||||||
|
deliveryAddress = *obj.ShippingAddress
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if theContact.MailingAddress == nil {
|
||||||
|
sugar.Errorf(
|
||||||
|
"ops.getDefaultDeliveryAddress: 💣 ⛔ default delivery contact has no email, id = %s",
|
||||||
|
obj.DefaultBackendID,
|
||||||
|
)
|
||||||
|
if obj.ShippingAddress == nil {
|
||||||
|
if obj.BillingAddress == nil {
|
||||||
|
return nil, fmt.Errorf("ops.GetDefaultDeliveryAddress: 💣 ⛔ can't find any valid addresses")
|
||||||
|
}
|
||||||
|
deliveryAddress = *obj.BillingAddress
|
||||||
|
} else {
|
||||||
|
deliveryAddress = *obj.ShippingAddress
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deliveryAddress = *theContact.MailingAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deliveryAddress.City == "" || deliveryAddress.State+deliveryAddress.StateCode == "" {
|
||||||
|
return nil, fmt.Errorf("ops.getDefaultDeliveryAddress: 💣 ⛔ city or state+statecode is blank: %v", deliveryAddress)
|
||||||
|
}
|
||||||
|
return &deliveryAddress, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetAccount is first class retrieval function
|
// GetAccount is first class retrieval function
|
||||||
func GetAccount(key string, principal *User) *Account {
|
func GetAccount(key string, principal *User) *Account {
|
||||||
if key == "" {
|
if key == "" {
|
||||||
|
@ -26,13 +64,13 @@ func GetAccount(key string, principal *User) *Account {
|
||||||
|
|
||||||
// GetAccountByID retrieves and enriches an Account object instance
|
// GetAccountByID retrieves and enriches an Account object instance
|
||||||
func GetAccountByID(recordID string, principal *User) (*Account, error) {
|
func GetAccountByID(recordID string, principal *User) (*Account, error) {
|
||||||
sugar.Debug("app.GetAccountByID: 📥")
|
sugar.Debug("GetAccountByID: 📥")
|
||||||
if recordID == "" {
|
if recordID == "" {
|
||||||
return nil, fmt.Errorf("app.getAccountByID: 💣 ⛔ key is blank")
|
return nil, fmt.Errorf("getAccountByID: 💣 ⛔ key is blank")
|
||||||
}
|
}
|
||||||
obj, ok := accountCache.get(recordID)
|
obj, ok := accountCache.get(recordID)
|
||||||
if ok {
|
if ok {
|
||||||
sugar.Debug("app.getAccountByID: 👍 🎯 📤")
|
sugar.Debug("getAccountByID: 👍 🎯 📤")
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
crmParams := accounts.NewGetAccountsParamsWithTimeout(getTimeout)
|
crmParams := accounts.NewGetAccountsParamsWithTimeout(getTimeout)
|
||||||
|
@ -47,7 +85,7 @@ func GetAccountByID(recordID string, principal *User) (*Account, error) {
|
||||||
}
|
}
|
||||||
finalObj := theObj.Enrich(principal)
|
finalObj := theObj.Enrich(principal)
|
||||||
accountCache.put(recordID, finalObj)
|
accountCache.put(recordID, finalObj)
|
||||||
sugar.Debug("app.getAccountByID: 👍 🆕 📤")
|
sugar.Debug("getAccountByID: 👍 🆕 📤")
|
||||||
return finalObj, nil
|
return finalObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +191,7 @@ func (obj *Account) Enrich(principal *User) *Account {
|
||||||
|
|
||||||
// GetCoordinate is a first class retrieval function
|
// GetCoordinate is a first class retrieval function
|
||||||
func (obj *Account) GetCoordinate(principal *User) *Coordinate {
|
func (obj *Account) GetCoordinate(principal *User) *Coordinate {
|
||||||
sugar.Debug("app.Account.getCoordinate: 📥")
|
sugar.Debug("Account.getCoordinate: 📥")
|
||||||
if obj.CoordinateID != "" { // if CoordinateID is set, then just get it
|
if obj.CoordinateID != "" { // if CoordinateID is set, then just get it
|
||||||
geoParams := coordinate.NewGetCoordinatesParamsWithTimeout(getTimeout)
|
geoParams := coordinate.NewGetCoordinatesParamsWithTimeout(getTimeout)
|
||||||
geoParams.CoordinateID = &obj.CoordinateID
|
geoParams.CoordinateID = &obj.CoordinateID
|
||||||
|
@ -168,7 +206,7 @@ func (obj *Account) GetCoordinate(principal *User) *Coordinate {
|
||||||
return obj
|
return obj
|
||||||
} // else get it via addresses, shipping #1, Business #2
|
} // else get it via addresses, shipping #1, Business #2
|
||||||
if obj.ShippingAddress.ToString() == "" && obj.BillingAddress.ToString() == "" {
|
if obj.ShippingAddress.ToString() == "" && obj.BillingAddress.ToString() == "" {
|
||||||
sugar.Errorf("app.Account.getCoordinate: 💣 ⛔ billing and shipping address both blank")
|
sugar.Errorf("Account.getCoordinate: 💣 ⛔ billing and shipping address both blank")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
theAddress := obj.ShippingAddress.ToString()
|
theAddress := obj.ShippingAddress.ToString()
|
||||||
|
@ -186,6 +224,6 @@ func (obj *Account) GetCoordinate(principal *User) *Coordinate {
|
||||||
for _, itm := range response.Payload.Data { // single iteration execution
|
for _, itm := range response.Payload.Data { // single iteration execution
|
||||||
swag = itm
|
swag = itm
|
||||||
}
|
}
|
||||||
sugar.Debug("app.Account.getCoordinate: 👍 📤")
|
sugar.Debug("Account.getCoordinate: 👍 📤")
|
||||||
return UnMarshalCoordinate(swag, principal)
|
return UnMarshalCoordinate(swag, principal)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
var accountingRuleCache = accountingRuleCacheType{
|
||||||
|
obj: map[string]map[string]*ledger_models.AccountingRule{},
|
||||||
|
}
|
||||||
|
|
||||||
|
type accountingRuleCacheType struct {
|
||||||
|
sync.RWMutex
|
||||||
|
obj map[string]map[string]*ledger_models.AccountingRule
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *accountingRuleCacheType) get(accountID string) (map[string]*ledger_models.AccountingRule, bool) {
|
||||||
|
m.RLock()
|
||||||
|
defer m.RUnlock()
|
||||||
|
r, ok := m.obj[accountID]
|
||||||
|
return r, ok
|
||||||
|
}
|
||||||
|
func (m *accountingRuleCacheType) put(accountID string, rules map[string]*ledger_models.AccountingRule) {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
m.obj[accountID] = rules
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_client/accounting_rule"
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetAccountingRulesByAccountID is a first class object retrieval method
|
||||||
|
func GetAccountingRulesByAccountID(
|
||||||
|
accountID string,
|
||||||
|
principal *User,
|
||||||
|
) (map[string]*ledger_models.AccountingRule, error) {
|
||||||
|
sugar.Debug("ops.getAccountingRulesByAccountID: 📥")
|
||||||
|
obj, ok := accountingRuleCache.get(accountID)
|
||||||
|
if ok {
|
||||||
|
sugar.Debugf("ops.getAccountingRulesByAccountID: 👍 📤 🎯 n = %v", len(obj))
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
ledgerParams := accounting_rule.NewGetAccountingRulesParamsWithTimeout(getTimeout)
|
||||||
|
ledgerParams.AccountID = accountID
|
||||||
|
response, restErr := ledgerClient.AccountingRule.GetAccountingRules(ledgerParams, principal.Auth)
|
||||||
|
if restErr != nil {
|
||||||
|
return nil, fmt.Errorf("ops.getAccountingRulesByAccountID: 💣 ⛔ %w", restErr)
|
||||||
|
}
|
||||||
|
theRules := map[string]*ledger_models.AccountingRule{}
|
||||||
|
for _, itm := range response.Payload.Data {
|
||||||
|
theRules[itm.Code] = itm
|
||||||
|
}
|
||||||
|
sugar.Debugf("ops.getAccountingRulesByAccountID: 👍 📤 n = %v", len(theRules))
|
||||||
|
accountingRuleCache.put(accountID, theRules)
|
||||||
|
return theRules, nil
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
var accountingRulesetCache = accountingRulesetCacheType{
|
||||||
|
obj: map[string]map[string]*ledger_models.AccountingRuleset{},
|
||||||
|
}
|
||||||
|
|
||||||
|
type accountingRulesetCacheType struct {
|
||||||
|
sync.RWMutex
|
||||||
|
obj map[string]map[string]*ledger_models.AccountingRuleset
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *accountingRulesetCacheType) get(accountID string) (map[string]*ledger_models.AccountingRuleset, bool) {
|
||||||
|
m.RLock()
|
||||||
|
defer m.RUnlock()
|
||||||
|
r, ok := m.obj[accountID]
|
||||||
|
return r, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *accountingRulesetCacheType) put(accountID string, rules map[string]*ledger_models.AccountingRuleset) {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
m.obj[accountID] = rules
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_client/accounting_ruleset"
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAccountingRulesetsByAccountID(
|
||||||
|
accountID string,
|
||||||
|
principal *User,
|
||||||
|
) (map[string]*ledger_models.AccountingRuleset, error) {
|
||||||
|
obj, ok := accountingRulesetCache.get(accountID)
|
||||||
|
if ok {
|
||||||
|
sugar.Debugf("ops.getAccountingRulesetsByAccountID: 👍 📤 🎯 n = %v", len(obj))
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
params := accounting_ruleset.NewGetAccountingRulesetsParamsWithTimeout(getTimeout)
|
||||||
|
params.AccountID = accountID
|
||||||
|
response, restErr := ledgerClient.AccountingRuleset.GetAccountingRulesets(params, principal.Auth)
|
||||||
|
if restErr != nil {
|
||||||
|
return nil, fmt.Errorf("ops.getAccountingRulesetsByAccountID: 💣 ⛔ %w", restErr)
|
||||||
|
}
|
||||||
|
theRulesets := map[string]*ledger_models.AccountingRuleset{}
|
||||||
|
for _, itm := range response.Payload.Data {
|
||||||
|
theRulesets[itm.Code] = itm
|
||||||
|
}
|
||||||
|
sugar.Debugf("ops.getAccountingRulesetsByAccountID: 👍 📤 n = %v", len(theRulesets))
|
||||||
|
accountingRulesetCache.put(accountID, theRulesets)
|
||||||
|
return theRulesets, nil
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/geo/geo_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GeocodeAddressParams struct {
|
||||||
|
BusinessAddress *Address
|
||||||
|
Account *Account
|
||||||
|
Ref string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GeocodeAddress(params GeocodeAddressParams, principal *User) (*geo_models.CoordinateBasic, error) {
|
||||||
|
if params.BusinessAddress == nil {
|
||||||
|
sugar.Infof("ops.geocodeAddress: ❗ Business Address is null, ref = %s", params.Ref)
|
||||||
|
deliveryAddress, acctErr := GetDefaultDeliveryAddress(params.Account, principal)
|
||||||
|
if acctErr != nil {
|
||||||
|
return nil, fmt.Errorf("ops.geocodeAddress: 💣 ⛔ can't determine default delivery address: %w", acctErr)
|
||||||
|
}
|
||||||
|
params.BusinessAddress = deliveryAddress
|
||||||
|
}
|
||||||
|
if params.BusinessAddress.City == "" {
|
||||||
|
sugar.Infof("ops.geocodeAddress: ❗ Business Address is blank, ref = %s", params.Ref)
|
||||||
|
deliveryAddress, acctErr := GetDefaultDeliveryAddress(params.Account, principal)
|
||||||
|
if acctErr != nil {
|
||||||
|
return nil, fmt.Errorf("ops.geocodeAddress: 💣 ⛔ can't determine default delivery address: %w", acctErr)
|
||||||
|
}
|
||||||
|
params.BusinessAddress = deliveryAddress
|
||||||
|
}
|
||||||
|
var situsCoordinate *geo_models.CoordinateBasic
|
||||||
|
aCoordinate, err := GetCoordinate(params.BusinessAddress, principal)
|
||||||
|
if err == nil {
|
||||||
|
situsCoordinate = aCoordinate
|
||||||
|
} else {
|
||||||
|
sugar.Infof("ops.geocodeAddress: ❗ can't geocode address: %w", err)
|
||||||
|
deliveryAddress, acctErr := GetDefaultDeliveryAddress(params.Account, principal)
|
||||||
|
if acctErr != nil {
|
||||||
|
return nil, fmt.Errorf("ops.geocodeAddress: 💣 ⛔ can't determine default delivery address: %w", acctErr)
|
||||||
|
}
|
||||||
|
aCoordinate, coordErr := GetCoordinate(deliveryAddress, principal)
|
||||||
|
if coordErr != nil {
|
||||||
|
return nil, fmt.Errorf("ops.geocodeAddress: 💣 ⛔ can't determine default delivery coordinates: %w", acctErr)
|
||||||
|
}
|
||||||
|
sugar.Infof("ops.geocodeAddress: ❗ alternate address used for ref = %s", params.Ref)
|
||||||
|
situsCoordinate = aCoordinate
|
||||||
|
}
|
||||||
|
return situsCoordinate, nil
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/geo/geo_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
var coordinateCache = coordinateCacheType{
|
||||||
|
obj: map[string]*geo_models.CoordinateBasic{},
|
||||||
|
}
|
||||||
|
|
||||||
|
type coordinateCacheType struct {
|
||||||
|
sync.RWMutex
|
||||||
|
obj map[string]*geo_models.CoordinateBasic
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *coordinateCacheType) get(addrStr string) (*geo_models.CoordinateBasic, bool) {
|
||||||
|
m.RLock()
|
||||||
|
defer m.RUnlock()
|
||||||
|
r, ok := m.obj[addrStr]
|
||||||
|
return r, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *coordinateCacheType) put(accountID string, coord *geo_models.CoordinateBasic) {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
m.obj[accountID] = coord
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/geo/geo_client/coordinate"
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/geo/geo_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetCoordinate is a first class object retrieval method
|
||||||
|
func GetCoordinate(addr *Address, principal *User) (*geo_models.CoordinateBasic, error) {
|
||||||
|
sugar.Debug("ops.getCoordinate: 📥")
|
||||||
|
if addr == nil {
|
||||||
|
return nil, fmt.Errorf("ops.getCoordinate: 💣 ⛔ Address cannot be nil")
|
||||||
|
}
|
||||||
|
if addr.ToString() == "" {
|
||||||
|
return nil, fmt.Errorf("ops.getCoordinate: 💣 ⛔ Address cannot be empty")
|
||||||
|
}
|
||||||
|
sugar.Debugf("ops.getCoordinate: 📏 address: %s", addr.ToString())
|
||||||
|
if addr.City == "" {
|
||||||
|
return nil, fmt.Errorf("ops.getCoordinate: 💣 ⛔ City cannot be blank")
|
||||||
|
}
|
||||||
|
obj, ok := coordinateCache.get(addr.ToString())
|
||||||
|
if ok {
|
||||||
|
sugar.Debugf("ops.GetCoordiante: 👍🏻 🎯 📤")
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
placeName := addr.City + ", " + addr.StateCode
|
||||||
|
if addr.StateCode == "" {
|
||||||
|
placeName = addr.City + ", " + addr.State
|
||||||
|
}
|
||||||
|
coordParams := coordinate.NewGetCoordinateBasicParamsWithTimeout(getTimeout)
|
||||||
|
theAddress := addr.ToString()
|
||||||
|
coordParams.PlaceName = &placeName
|
||||||
|
coordParams.Address = &theAddress
|
||||||
|
response, geoErr := geoClient.Coordinate.GetCoordinateBasic(coordParams, principal.Auth)
|
||||||
|
if geoErr != nil {
|
||||||
|
return nil, fmt.Errorf("ops.getCoordinate: 💣 ⛔ failed, %s (%w)", *coordParams.Address, geoErr)
|
||||||
|
}
|
||||||
|
if len(response.Payload.Data) != 1 {
|
||||||
|
return nil, fmt.Errorf("ops.getCoordinate: 💣 ⛔ one and only one coordinate record should be returned")
|
||||||
|
}
|
||||||
|
sugar.Debugf("ops.getCoordinate: ✅ geo records retrieved = %d", len(response.Payload.Data))
|
||||||
|
var coord geo_models.CoordinateBasic
|
||||||
|
for _, itm := range response.Payload.Data {
|
||||||
|
coord = *itm
|
||||||
|
}
|
||||||
|
coordinateCache.put(addr.ToString(), &coord)
|
||||||
|
sugar.Debug("ops.getCoordinate: 👍 📤")
|
||||||
|
return &coord, nil
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
var glBalanceCache = glBalanceCacheType{
|
||||||
|
obj: map[string]map[string]*ledger_models.GlBalance{},
|
||||||
|
}
|
||||||
|
|
||||||
|
type glBalanceCacheType struct {
|
||||||
|
sync.RWMutex
|
||||||
|
obj map[string]map[string]*ledger_models.GlBalance
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *glBalanceCacheType) get(periodID, glAccountID string) (*ledger_models.GlBalance, bool) {
|
||||||
|
m.RLock()
|
||||||
|
defer m.RUnlock()
|
||||||
|
r, ok := m.obj[periodID][glAccountID]
|
||||||
|
return r, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *glBalanceCacheType) put(periodID, glAccountID string, glBalance *ledger_models.GlBalance) {
|
||||||
|
m.init(periodID)
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
m.obj[periodID][glAccountID] = glBalance
|
||||||
|
}
|
||||||
|
func (m *glBalanceCacheType) init(periodID string) {
|
||||||
|
m.RLock()
|
||||||
|
defer m.RUnlock()
|
||||||
|
_, ok := m.obj[periodID]
|
||||||
|
if !ok {
|
||||||
|
m.obj[periodID] = map[string]*ledger_models.GlBalance{}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_client/gl_balance"
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GlBalanceParams is a parameter struct
|
||||||
|
type GlBalanceParams struct {
|
||||||
|
glAccountID string
|
||||||
|
periodID string
|
||||||
|
principal *User
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlBalanceByParams is a GL balance helper function
|
||||||
|
func GetGlBalanceByParams(params GlBalanceParams) *ledger_models.GlBalance {
|
||||||
|
sugar.Debug("ops.getGlBalanceByParams: 📥")
|
||||||
|
obj, ok := glBalanceCache.get(params.periodID, params.glAccountID)
|
||||||
|
if ok {
|
||||||
|
sugar.Debug("ops.getGlBalanceByParams: 👍 📤 🎯")
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
ledgerParams := gl_balance.NewGetGlBalancesParamsWithTimeout(getTimeout)
|
||||||
|
ledgerParams.GlAccountID = ¶ms.glAccountID
|
||||||
|
ledgerParams.PeriodID = ¶ms.periodID
|
||||||
|
response, restErr := ledgerClient.GlBalance.GetGlBalances(ledgerParams, params.principal.Auth)
|
||||||
|
if restErr != nil {
|
||||||
|
sugar.Errorf("ops.getGlBalanceByParams: 💣 ⛔ %s", restErr.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
theGlBalance := &ledger_models.GlBalance{}
|
||||||
|
for _, itm := range response.Payload.Data {
|
||||||
|
theGlBalance = itm // singleton
|
||||||
|
}
|
||||||
|
glBalanceCache.put(params.periodID, params.glAccountID, theGlBalance)
|
||||||
|
sugar.Debugf("ops.getGlBalanceByParams: 👍 📤")
|
||||||
|
return theGlBalance
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
var periodCache = periodCacheType{
|
||||||
|
obj: map[string]map[string]*CalendarPeriod{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// periodCacheType maps [accountID][dateString]
|
||||||
|
type periodCacheType struct {
|
||||||
|
sync.RWMutex
|
||||||
|
obj map[string]map[string]*CalendarPeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *periodCacheType) get(accountID, dateStr string) (*CalendarPeriod, bool) {
|
||||||
|
m.RLock()
|
||||||
|
defer m.RUnlock()
|
||||||
|
r, ok := m.obj[accountID][dateStr]
|
||||||
|
return r, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *periodCacheType) put(accountID, dateStr string, period *CalendarPeriod) {
|
||||||
|
m.init(accountID)
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
m.obj[accountID][dateStr] = period
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *periodCacheType) init(accountID string) {
|
||||||
|
m.RLock()
|
||||||
|
defer m.RUnlock()
|
||||||
|
_, ok := m.obj[accountID]
|
||||||
|
if !ok {
|
||||||
|
m.obj[accountID] = map[string]*CalendarPeriod{}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_client/period"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CalendarPeriod is a parameter type
|
||||||
|
type CalendarPeriod struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
StartDate time.Time
|
||||||
|
EndDate time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPeriodParams is a parameter type
|
||||||
|
type GetPeriodParams struct {
|
||||||
|
Date time.Time
|
||||||
|
AccountID string
|
||||||
|
Principal *User
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPeriodIDByDate is a period helper function
|
||||||
|
func GetPeriodIDByDate(params GetPeriodParams) (string, error) {
|
||||||
|
sugar.Debug("ops.getPeriodIDByDate: 📥")
|
||||||
|
obj, ok := periodCache.get(params.AccountID, params.Date.Format(dateFormat))
|
||||||
|
if ok {
|
||||||
|
sugar.Debugf("ops.getPeriodIDByDate: 👍 📤 🎯")
|
||||||
|
return obj.ID, nil
|
||||||
|
}
|
||||||
|
ledgerDate := params.Date.Format(dateFormat)
|
||||||
|
ledgerParams := period.NewGetPeriodsParamsWithTimeout(getTimeout)
|
||||||
|
ledgerParams.AccountID = ¶ms.AccountID
|
||||||
|
ledgerParams.Date = &ledgerDate
|
||||||
|
response, restErr := ledgerClient.Period.GetPeriods(ledgerParams, params.Principal.Auth)
|
||||||
|
if restErr != nil {
|
||||||
|
return "", fmt.Errorf("ops.getPeriodIDByDate: 💣 ⛔ dateStr = %s (%w)", params.Date, restErr)
|
||||||
|
}
|
||||||
|
// this loop should iterate just once
|
||||||
|
thePeriod := &CalendarPeriod{}
|
||||||
|
for _, itm := range response.Payload.Data {
|
||||||
|
startDate, _ := time.Parse(dateTimeFormat, itm.StartDate)
|
||||||
|
endDate, _ := time.Parse(dateTimeFormat, itm.EndDate)
|
||||||
|
thePeriod = &CalendarPeriod{
|
||||||
|
ID: itm.ID,
|
||||||
|
EndDate: endDate,
|
||||||
|
Name: itm.Name,
|
||||||
|
StartDate: startDate,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
periodCache.put(params.AccountID, params.Date.Format(dateFormat), thePeriod)
|
||||||
|
sugar.Debugf("ops.getPeriodIDByDate: 👍 📤 %s", thePeriod.Name)
|
||||||
|
return thePeriod.ID, nil
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"code.tnxs.net/taxnexus/lib/api/auth0/auth0_client"
|
"code.tnxs.net/taxnexus/lib/api/auth0/auth0_client"
|
||||||
"code.tnxs.net/taxnexus/lib/api/crm/crm_client"
|
"code.tnxs.net/taxnexus/lib/api/crm/crm_client"
|
||||||
"code.tnxs.net/taxnexus/lib/api/geo/geo_client"
|
"code.tnxs.net/taxnexus/lib/api/geo/geo_client"
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/ledger/ledger_client"
|
||||||
"code.tnxs.net/taxnexus/lib/api/ops/ops_client"
|
"code.tnxs.net/taxnexus/lib/api/ops/ops_client"
|
||||||
"code.tnxs.net/taxnexus/lib/api/regs/regs_client"
|
"code.tnxs.net/taxnexus/lib/api/regs/regs_client"
|
||||||
"code.tnxs.net/taxnexus/lib/api/stash/stash_client"
|
"code.tnxs.net/taxnexus/lib/api/stash/stash_client"
|
||||||
|
@ -27,6 +28,7 @@ var config = Configuration{}
|
||||||
var configured = false
|
var configured = false
|
||||||
var crmClient = crm_client.Default
|
var crmClient = crm_client.Default
|
||||||
var geoClient = geo_client.Default
|
var geoClient = geo_client.Default
|
||||||
|
var ledgerClient = ledger_client.Default
|
||||||
var opsClient = ops_client.Default
|
var opsClient = ops_client.Default
|
||||||
var regsClient = regs_client.Default
|
var regsClient = regs_client.Default
|
||||||
var stashClient = stash_client.Default
|
var stashClient = stash_client.Default
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/regs/regs_client/transaction"
|
||||||
|
"code.tnxs.net/taxnexus/lib/api/regs/regs_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PostTransactions is a first class object type storage method
|
||||||
|
func PostTransactions(objList []*TaxTransaction, principal *User) error {
|
||||||
|
swagList := []*regs_models.Transaction{}
|
||||||
|
for _, itm := range objList {
|
||||||
|
swagList = append(swagList, ®s_models.Transaction{
|
||||||
|
AccountID: itm.AccountID,
|
||||||
|
TaxTransactionID: itm.ID,
|
||||||
|
TaxTypeID: itm.TaxTypeID,
|
||||||
|
Valid: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
regsParams := transaction.NewPostTransactionsParamsWithTimeout(postTimeout)
|
||||||
|
regsParams.TransactionRequest = ®s_models.TransactionRequest{
|
||||||
|
Data: swagList,
|
||||||
|
}
|
||||||
|
_, err := regsClient.Transaction.PostTransactions(regsParams, principal.Auth)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue