v0.1.43 v0.1.43
Vernon Keenan 2021-01-28 12:00:21 -08:00
parent a220b714aa
commit 530e351912
7 changed files with 246 additions and 19 deletions

View File

@ -24,7 +24,7 @@ func GetAccount(key string, principal *User) *Account {
return acct return acct
} }
// GetAccountByID is first class retrieval function // 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("app.GetAccountByID: 📥")
if recordID == "" { if recordID == "" {
@ -41,13 +41,114 @@ func GetAccountByID(recordID string, principal *User) (*Account, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
var newObj *Account var theObj *Account
for _, itm := range response.Payload.Data { // single iteration execution for _, itm := range response.Payload.Data { // single iteration execution
newObj = UnMarshalAccount(itm) theObj = UnMarshalAccount(itm)
} }
accountCache.put(recordID, newObj) finalObj := theObj.Enrich(principal)
accountCache.put(recordID, finalObj)
sugar.Debug("app.getAccountByID: 👍 🆕 📤") sugar.Debug("app.getAccountByID: 👍 🆕 📤")
return newObj, nil return finalObj, nil
}
// Enrich adds subordinate objects to a first class object and returns a copy
func (obj *Account) Enrich(principal *User) *Account {
return &Account{
ID: obj.ID,
AccountNumber: obj.AccountNumber,
AccountSource: obj.AccountSource,
Active: obj.Active,
AdministrativeLevel: obj.AdministrativeLevel,
Amount: obj.Amount,
AmountInvoiced: obj.AmountInvoiced,
AmountPaid: obj.AmountPaid,
AnnualRevenue: obj.AnnualRevenue,
Balance: obj.Balance,
BillingAddress: obj.BillingAddress,
BillingContactID: obj.BillingContactID,
BillingContact: GetContact(obj.BillingContactID, principal),
BillingPreference: obj.BillingPreference,
BusinessAddress: obj.BusinessAddress,
CannabisCustomer: obj.CannabisCustomer,
ChannelProgramLevelName: obj.ChannelProgramLevelName,
ChannelProgramName: obj.ChannelProgramName,
ClientEndDate: obj.ClientEndDate,
ClientStartDate: obj.ClientStartDate,
CompanyID: obj.CompanyID,
Coordinate: obj.GetCoordinate(principal),
CoordinateID: obj.CoordinateID,
CreatedByID: obj.CreatedByID,
CreatedDate: obj.CreatedDate,
CustomerID: obj.CustomerID,
CustomerPriority: obj.CustomerPriority,
DandBCompanyID: obj.DandBCompanyID,
DBA: obj.DBA,
DefaultAddress: obj.DefaultAddress,
DefaultBackendID: obj.DefaultBackendID,
DefaultBackend: GetBackend(obj.DefaultBackendID, principal),
DefaultDeliveryContactID: obj.DefaultDeliveryContactID,
DefaultEndUserID: obj.DefaultEndUserID,
DefaultEndUser: GetContact(obj.DefaultEndUserID, principal),
Description: obj.Description,
DunsNumber: obj.DunsNumber,
EIN: obj.EIN,
Email: obj.Email,
EnrollmentStatus: obj.EnrollmentStatus,
Fax: obj.Fax,
Industry: obj.Industry,
IsCustomerPortal: obj.IsCustomerPortal,
IsPartner: obj.IsPartner,
ISPCustomer: obj.ISPCustomer,
Jigsaw: obj.Jigsaw,
LastModifiedByID: obj.LastModifiedByID,
LastModifiedDate: obj.LastModifiedDate,
MSPCustomer: obj.MSPCustomer,
NaicsCode: obj.NaicsCode,
NaicsDesc: obj.NaicsDesc,
Name: obj.Name,
NumberOfEmployees: obj.NumberOfEmployees,
NumberOfLocations: obj.NumberOfLocations,
OpenCharges: obj.OpenCharges,
OrderContactID: obj.OrderContactID,
OrderContact: GetContact(obj.OrderContactID, principal),
OrderEmail: obj.OrderEmail,
OwnerID: obj.OwnerID,
Ownership: obj.Ownership,
ParentFK: obj.ParentFK,
ParentID: obj.ParentID,
Phone: obj.Phone,
PlaceID: obj.PlaceID,
PreparerID: obj.PreparerID,
Rating: obj.Rating,
RatingEngineID: obj.RatingEngineID,
Ref: obj.Ref,
RevenueBase: obj.RevenueBase,
RevenueNet: obj.RevenueNet,
RevenueNotTaxable: obj.RevenueNotTaxable,
ShippingAddress: obj.ShippingAddress,
ShippingCensusTract: obj.ShippingCensusTract,
ShippingContactID: obj.ShippingContactID,
ShippingContact: GetContact(obj.ShippingContactID, principal),
ShippingCounty: obj.ShippingCounty,
SIC: obj.SIC,
SicDesc: obj.SicDesc,
Site: obj.Site,
Status: obj.Status,
TaxExemption: obj.TaxExemption,
TaxOnTax: obj.TaxOnTax,
TelecomCustomer: obj.TelecomCustomer,
TenantID: obj.TenantID,
TickerSymbol: obj.TickerSymbol,
TradeStyle: obj.TradeStyle,
Type: obj.Type,
UnappliedPayments: obj.UnappliedPayments,
UnitBase: obj.UnitBase,
UpsellOpportunity: obj.UpsellOpportunity,
Website: obj.Website,
WHMCSClientID: obj.WHMCSClientID,
XeroContactID: obj.XeroContactID,
YearStarted: obj.YearStarted,
}
} }
// GetCoordinate is a first class retrieval function // GetCoordinate is a first class retrieval function

View File

@ -93,6 +93,7 @@ type Account struct {
DefaultBackend *Backend DefaultBackend *Backend
DefaultDeliveryContactID string DefaultDeliveryContactID string
DefaultEndUserID string DefaultEndUserID string
DefaultEndUser *Contact
Description string Description string
DunsNumber string DunsNumber string
EIN string EIN string

25
app/backend-cache.go Normal file
View File

@ -0,0 +1,25 @@
package app
import "sync"
var backendCache = backendCacheType{
obj: map[string]*Backend{},
}
type backendCacheType struct {
sync.RWMutex
obj map[string]*Backend
}
func (m *backendCacheType) get(recordID string) (*Backend, bool) {
m.RLock()
defer m.RUnlock()
r, ok := m.obj[recordID]
return r, ok
}
func (m *backendCacheType) put(recordID string, itm *Backend) {
m.Lock()
defer m.Unlock()
m.obj[recordID] = itm
}

49
app/backend-services.go Normal file
View File

@ -0,0 +1,49 @@
package app
import (
"fmt"
"code.tnxs.net/taxnexus/lib/api/regs/regs_client/backend"
)
// GetBackend is a first class object retrieval function
func GetBackend(id string, principal *User) *Backend {
if id == "" {
return nil
}
c, ok := backendCache.get(id)
if ok {
return c
}
c, err := GetBackendByID(id, principal)
if err != nil {
return nil
}
return c
}
// GetBackendByID is a first class object retrieval function
func GetBackendByID(key string, principal *User) (*Backend, error) {
sugar.Debugf("app.getBackendByID: 📥")
if key == "" {
return nil, fmt.Errorf("app.getBackendByID: 💣 ⛔ key is blank")
}
obj, ok := backendCache.get(key)
if ok {
sugar.Debugf("app.getBackendByID: 👍 🎯 📤")
return obj, nil
}
params := backend.NewGetBackendsParamsWithTimeout(getTimeout)
params.BackendID = &key
response, err := regsClient.Backend.GetBackends(params, principal.Auth)
if err != nil {
return nil, err
}
var newObj *Backend
for _, itm := range response.Payload.Data { // single iteration execution
newObj = UnMarshalBackend(itm)
}
backendCache.put(key, newObj)
sugar.Debugf("app.getBackendByID: 👍 🆕 📤")
return newObj, nil
}

View File

@ -2,27 +2,25 @@ package app
import ( import (
"sync" "sync"
"code.tnxs.net/taxnexus/lib/api/crm/crm_models"
) )
var companyCache = companyCacheType{ var companyCache = companyCacheType{
obj: map[string]*crm_models.Company{}, obj: map[string]*Company{},
} }
type companyCacheType struct { type companyCacheType struct {
sync.RWMutex sync.RWMutex
obj map[string]*crm_models.Company obj map[string]*Company
} }
func (m *companyCacheType) get(recordID string) (*crm_models.Company, bool) { func (m *companyCacheType) get(recordID string) (*Company, bool) {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
r, ok := m.obj[recordID] r, ok := m.obj[recordID]
return r, ok return r, ok
} }
func (m *companyCacheType) put(recordID string, itm *crm_models.Company) { func (m *companyCacheType) put(recordID string, itm *Company) {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
m.obj[recordID] = itm m.obj[recordID] = itm

View File

@ -4,11 +4,10 @@ import (
"fmt" "fmt"
"code.tnxs.net/taxnexus/lib/api/crm/crm_client/companies" "code.tnxs.net/taxnexus/lib/api/crm/crm_client/companies"
"code.tnxs.net/taxnexus/lib/api/crm/crm_models"
) )
// GetCompany is a first class object retrieval function // GetCompany is a first class object retrieval function
func GetCompany(id string, principal *User) *crm_models.Company { func GetCompany(id string, principal *User) *Company {
if id == "" { if id == "" {
return nil return nil
} }
@ -24,7 +23,7 @@ func GetCompany(id string, principal *User) *crm_models.Company {
} }
// GetCompanyByID is a first class object retrieval function // GetCompanyByID is a first class object retrieval function
func GetCompanyByID(key string, principal *User) (*crm_models.Company, error) { func GetCompanyByID(key string, principal *User) (*Company, error) {
sugar.Debugf("app.getCompanyByID: 📥") sugar.Debugf("app.getCompanyByID: 📥")
if key == "" { if key == "" {
return nil, fmt.Errorf("app.getCompanyByID: 💣 ⛔ key is blank") return nil, fmt.Errorf("app.getCompanyByID: 💣 ⛔ key is blank")
@ -40,18 +39,70 @@ func GetCompanyByID(key string, principal *User) (*crm_models.Company, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
var obj *crm_models.Company var obj *Company
for _, itm := range response.Payload.Data { // single iteration execution for _, itm := range response.Payload.Data { // single iteration execution
obj = itm obj = UnMarshalCompany(itm, principal)
} }
companyCache.put(key, obj) finalObj := obj.Enrich(principal)
companyCache.put(key, finalObj)
sugar.Debugf("app.getCompanyByID: 👍 🆕 📤") sugar.Debugf("app.getCompanyByID: 👍 🆕 📤")
return obj, nil return finalObj, nil
} }
const defaultCompanyID = "6ff8326f-79b7-40ae-afc7-390eca182b1b" // todo #3 Don't hardcode company ID const defaultCompanyID = "6ff8326f-79b7-40ae-afc7-390eca182b1b" // todo #3 Don't hardcode company ID
// GetDefaultCompany returns the default company // GetDefaultCompany returns the default company
func GetDefaultCompany(principal *User) *crm_models.Company { func GetDefaultCompany(principal *User) *Company {
return GetCompany(defaultCompanyID, principal) return GetCompany(defaultCompanyID, principal)
} }
// Enrich adds subordinate objects to a first class object and returns a copy
func (obj *Company) Enrich(principal *User) *Company {
return &Company{
ID: obj.ID,
Account: GetAccount(obj.AccountID, principal),
AccountID: obj.AccountID,
AccountNumberPrefix: obj.AccountNumberPrefix,
AdvancePeriodID: obj.AdvancePeriodID,
BillingAddress: obj.BillingAddress,
BillingAdvice: obj.BillingAdvice,
BillingContactID: obj.BillingContactID,
BillingContact: GetContact(obj.BillingContactID, principal),
BillingEmail: obj.BillingEmail,
BillingPhone: obj.BillingPhone,
BillingWebsite: obj.BillingWebsite,
CoaTemplateID: obj.CoaTemplateID,
ColorAccent1: obj.ColorAccent1,
ColorAccent2: obj.ColorAccent2,
ColorPrimary: obj.ColorPrimary,
ClosedPeriodID: obj.ClosedPeriodID,
CreatedByID: obj.CreatedByID,
CreatedDate: obj.CreatedDate,
CurrentPeriodID: obj.CurrentPeriodID,
CurrentPeriodStatus: obj.CurrentPeriodStatus,
CustomerSuccessID: obj.CustomerSuccessID,
CustomerSuccess: GetContact(obj.CustomerSuccessID, principal),
DateClosed: obj.DateClosed,
DefaultAddress: obj.DefaultAddress,
DefaultCompany: obj.DefaultCompany,
FontBody: obj.FontBody,
FontHeading: obj.FontHeading,
FontHeadingNarrow: obj.FontHeadingNarrow,
FontLink: obj.FontLink,
FontMono: obj.FontMono,
International: obj.International,
LastAccountNumber: obj.LastAccountNumber,
LastModifiedByID: obj.LastModifiedByID,
LastModifiedDate: obj.LastModifiedDate,
LastTaxtypeNumber: obj.LastTaxtypeNumber,
Logo: obj.Logo,
Name: obj.Name,
OwnerID: obj.OwnerID,
Preparer: GetContact(obj.PreparerID, principal),
PreparerID: obj.PreparerID,
PricebookID: obj.PricebookID,
TenantID: obj.TenantID,
UserTechLead: GetContact(obj.UserTechLeadID, principal),
UserTechLeadID: obj.UserTechLeadID,
}
}

View File

@ -9,6 +9,7 @@ import (
"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/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/stash/stash_client" "code.tnxs.net/taxnexus/lib/api/stash/stash_client"
"code.tnxs.net/taxnexus/lib/app/logger" "code.tnxs.net/taxnexus/lib/app/logger"
httptransport "github.com/go-openapi/runtime/client" httptransport "github.com/go-openapi/runtime/client"
@ -25,6 +26,7 @@ var geoClient = geo_client.Default
var crmClient = crm_client.Default var crmClient = crm_client.Default
var stashClient = stash_client.Default var stashClient = stash_client.Default
var opsClient = ops_client.Default var opsClient = ops_client.Default
var regsClient = regs_client.Default
var configured = false var configured = false
var apiUsers map[string]User var apiUsers map[string]User