Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
10.00% covered (danger)
10.00%
65 / 650
27.40% covered (danger)
27.40%
57 / 208
CRAP
0.00% covered (danger)
0.00%
0 / 1
Store
10.00% covered (danger)
10.00%
65 / 650
27.40% covered (danger)
27.40%
57 / 208
45084.42
0.00% covered (danger)
0.00%
0 / 1
 __construct
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
2.03
 createStore
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
 setTextMessageService
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
 createStoreFromRowArray
0.00% covered (danger)
0.00%
0 / 88
0.00% covered (danger)
0.00%
0 / 1
2
 getLoyaltyConfig
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 insert
0.00% covered (danger)
0.00%
0 / 81
0.00% covered (danger)
0.00%
0 / 1
2
 update
0.00% covered (danger)
0.00%
0 / 81
0.00% covered (danger)
0.00%
0 / 1
2
 getCompanyName
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
56
 getLoyaltyGroup
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUnusedInstallKey
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 updateWiwToken
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 updateQbAccessToken
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 updateQbRefreshToken
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 updateBillingActive
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 updateWiwLocationID
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 enableWiw
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 getAllMassSMS
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
30
 getOptTotals
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 setDev
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDev
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCcList
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCcList
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSmsPromoID
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSmsPromoID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSmsPromoKeyword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSmsPromoKeyword
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setStoreNum
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStoreNum
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setStoreType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStoreType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setTypeNum
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTypeNum
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setAddress
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAddress
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setApiKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getApiKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCcAPI
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCcAPI
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCcToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCcToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCcRefreshToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCcRefreshToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCcTokenExpiration
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCcTokenExpiration
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCcEnabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCcEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updateCcTokens
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 updateCcList
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 disconnectCc
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 isCcConnected
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 setCity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCity
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDbName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDbName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setPhone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPhone
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSmsAccountID
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSmsAccountID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSmsKeyword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSmsKeyword
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setState
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getState
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setTimeZone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTimeZone
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setZipcode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getZipcode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setMinutesPerContainer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMinutesPerContainer
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setWaitTimeType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWaitTimeType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setTwilioPhone
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTwilioPhone
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSmsType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSmsType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSmsPromoMessage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSmsPromoMessage
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRequirePass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRequirePass
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setReferralSystem
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getReferralSystem
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEstimateInterval
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEstimateInterval
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEnableInterval
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEnableInterval
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAddSortersToEstimate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setAddSortersToEstimate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStatMinSeconds
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setStatMinSeconds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStatMaxSeconds
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setStatMaxSeconds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRecentBuysMaxHours
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRecentBuysMaxHours
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLoyaltySystem
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setLoyaltySystem
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBuySurvey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBuySurvey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRcEnable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRcEnable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRcLine1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRcLine1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRcLine2
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRcLine2
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRcTagLine
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRcTagLine
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRcValidDays
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRcValidDays
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTransTexts
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setTransTexts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEmail
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEmail
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAutomation
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setAutomation
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDb
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDb
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEnableWaitTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEnableWaitTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDrsApiKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDrsApiKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSurveySMSText
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSurveySMSText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWiwToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setWiwToken
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWiwEnable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setWiwEnable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWiwLocationID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setWiwLocationID
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPostBuySMS
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setPostBuySMS
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActive
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setActive
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getShopifyAPIKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setShopifyAPIKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getShopifyURL
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setShopifyURL
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getShopifyPassword
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setShopifyPassword
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getShopifyLocationID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setShopifyLocationID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBillingActive
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBillingActive
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBuyTextSMSType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBuyTextSMSType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getYellowTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setYellowTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRedTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRedTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFiveStarsStoreID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setFiveStarsStoreID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFiveStarsSoftwareID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setFiveStarsSoftwareID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFiveStarsTaxIncluded
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setFiveStarsTaxIncluded
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFiveStarsBuysIncluded
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setFiveStarsBuysIncluded
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFiveStarsPointsRatio
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setFiveStarsPointsRatio
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEnableQueueSignIn
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEnableQueueSignIn
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getQbAccessToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setQbAccessToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQbRefreshToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setQbRefreshToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQbAccessTokenExpiration
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setQbAccessTokenExpiration
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQbRefreshTokenExpiration
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setQbRefreshTokenExpiration
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDigitalSignType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDigitalSignType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getQbRealmID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setQbRealmID
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQbEnabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setQbEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getQbLastSync
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setQbLastSync
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isQbConfigured
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 updateQbStatus
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getBillingType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBillingType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getNextBillingDate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setNextBillingDate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBillingRate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBillingRate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBillingDiscount
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBillingDiscount
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBillingDiscountDate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBillingDiscountDate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEmployeeSource
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getHomebaseApiKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setHomebaseApiKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHomebaseLocationId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setHomebaseLocationId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHomebaseEnable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setHomebaseEnable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSchedulingProvider
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSchedulingProvider
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDefaultOpenTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDefaultOpenTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDefaultCloseTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDefaultCloseTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHoursLastUpdated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setHoursLastUpdated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHoursUpdatedByUserId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setHoursUpdatedByUserId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFeatureFlag
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2
3namespace BuyerKiosk\Core;
4
5use BuyerKiosk\SMS\TextMessageService\VonageTextSender;
6use BuyerKiosk\SMS\TextMessageService\TwilioTextSender;
7use BuyerKiosk\SMS\TextMessageService\TextMessageService;
8
9class Store
10{
11    public $id;
12    public $typeNum;
13    public $storeType;
14    public $storeNum;
15    public $dbName;
16    public $timezone;
17    public $apiKey;
18    public $smsType;
19    public $smsKeyword;
20    public $smsAccountID;
21    public $smsPromoKeyword;
22    public $smsPromoMessage;
23    public $smsPromoID;
24    public $twilioPhone;
25    public $ccAPI;
26    public $ccToken;
27    public $ccRefreshToken;
28    public $ccTokenExpiration;
29    public $ccEnabled;
30    public $ccList;
31    public $address;
32    public $city;
33    public $state;
34    public $zipcode;
35    public $phone;
36    public $dev;
37    public $waitTimeType;
38    public $minutesPerContainer;
39    public $requirePass;
40    public $referralSystem;
41    public $loyaltySystem;
42    public $estimateInterval;
43    public $enableInterval;
44    public $addSortersToEstimate;
45    public $statMinSeconds;
46    public $statMaxSeconds;
47    public $recentBuysMaxHours;
48    public $buySurvey;
49    public $email;
50    public $automation;
51    public $loyaltyConfig;
52    public $enableWaitTime;
53    public $postBuySMS;
54    public $drsApiKey;
55    public $transTexts;
56    public $active;
57    public $buyTextSMSType;
58    public $yellowTime;
59    public $redTime;
60    public $enableQueueSignIn;
61
62    //FiveStarsAPI Config
63    public $fiveStarsStoreID;
64    public $fiveStarsSoftwareID;
65    public $fiveStarsTaxIncluded;
66    public $fiveStarsBuysIncluded;
67    public $fiveStarsPointsRatio;
68
69    //Receipt Coupon Config
70    public $rcEnable;
71    public $rcLine1;
72    public $rcLine2;
73    public $rcTagLine;
74    public $rcValidDays;
75
76    //Wiw Integration
77    public $wiwToken;
78    public $wiwEnable;
79    public $wiwLocationID;
80
81    //Homebase Integration
82    public $homebaseApiKey;
83    public $homebaseLocationId;
84    public $homebaseEnable;
85
86    //Scheduling Integration
87    public $schedulingProvider;
88
89    //Store Hours Configuration (Spec 018)
90    public $defaultOpenTime = '09:00';
91    public $defaultCloseTime = '21:00';
92    public $hoursLastUpdated = null;
93    public $hoursUpdatedByUserId = null;
94
95    //Shopify Integration
96    public $shopifyAPIKey;
97    public $shopifyURL;
98    public $shopifyPassword;
99    public $shopifyLocationID;
100
101    //Quickbooks Integration
102    public $qbAccessToken;
103    public $qbRefreshToken;
104    public $qbAccessTokenExpiration;
105    public $qbRefreshTokenExpiration;
106    public $qbRealmID;
107    public $qbEnabled;
108    public $qbLastSync;
109
110    //Billing
111    public $billingActive;
112    public $billingType;
113    public $nextBillingDate;
114    public $billingRate;
115    public $billingDiscount;
116    public $billingDiscountDate;
117
118
119    //database
120    //@var $db \PDO
121    private $db;
122
123    //SurveyTexts
124    public $surveySMSText;
125
126    public $digitalSignType;
127    public $dsWeatherBar;
128
129    //database
130    //@var $textMessageService \BuyerKiosk\SMS\TextMessageService\TextMessageService
131    public $textMessageService;
132
133    public function __construct($id = null)
134    {
135        if (isset($id)) {
136            return $this->createStore($id);
137        }
138        $service = new VonageTextSender($this);
139        $this->textMessageService = new TextMessageService($service, $this, $this->db);
140        return true;
141    }
142
143    public function createStore($id)
144    {
145
146        global $db_name;
147        $db = dbConnectByName($db_name);
148        $this->db = $db;
149        $stmt = $db->prepare("SELECT * FROM stores WHERE typeNum = :typeNum LIMIT 1");
150        $stmt->bindParam(':typeNum', $id, \PDO::PARAM_STR);
151        $stmt->execute();
152        $store = $stmt;
153
154        if ($store) {
155            if ($store->rowCount() > 0) {
156                $row = $store->fetch(\PDO::FETCH_ASSOC);
157            } else {
158                return false;
159            }
160        } else {
161            return false;
162        }
163
164        //stores Table Values
165        $this->createStoreFromRowArray($row);
166        return true;
167    }
168
169    private function setTextMessageService() {
170        switch ($this->buyTextSMSType) {
171            case 0:
172                $service = new VonageTextSender($this);
173                break;
174            case 1:
175                $service = new TwilioTextSender($this);
176                break;
177            default:
178                $service = new VonageTextSender($this);
179                break;
180        }
181        $this->textMessageService = new TextMessageService($service, $this, $this->db);
182        return true;
183    }
184
185    public function createStoreFromRowArray($row)
186    {
187        //stores Table Values
188        $this->id = $row['id'];
189        $this->dbName = $row['dbName'];
190        $this->storeType = $row['storeType'];
191        $this->storeNum = $row['storeNum'];
192        $this->address = $row['address'];
193        $this->apiKey = $row['apiKey'];
194        $this->smsType = $row['smsType'];
195        $this->ccAPI = $row['ccAPI'];
196        $this->ccToken = $row['ccToken'];
197        $this->ccRefreshToken = $row['ccRefreshToken'] ?? null;
198        $this->ccTokenExpiration = $row['ccTokenExpiration'] ?? null;
199        $this->ccEnabled = $row['ccEnabled'] ?? 0;
200        $this->ccList = $row['ccList'];
201        $this->city = $row['city'];
202        $this->typeNum = $row['typeNum'];
203        $this->phone = $row['phone'];
204        $this->smsAccountID = $row['smsAccountID'];
205        $this->smsKeyword = $row['smsKeyword'];
206        $this->smsPromoID = $row['smsPromoID'];
207        $this->smsPromoKeyword = $row['smsPromoKeyword'];
208        $this->smsPromoMessage = $row['smsPromoMessage'];
209        $this->twilioPhone = $row['twilioPhone'];
210        $this->state = $row['state'];
211        $this->zipcode = $row['zipcode'];
212        $this->timezone = $row['timezone'];
213        $this->dev = $row['dev'];
214        $this->waitTimeType = $row['waitTimeType'];
215        $this->minutesPerContainer = $row['minutesPerContainer'];
216        $this->requirePass = $row['requirePass'];
217        $this->referralSystem = $row['referralSystem'];
218        $this->loyaltySystem = $row['loyaltySystem'];
219        $this->estimateInterval = $row['estimateInterval'];
220        $this->enableInterval = $row['enableInterval'];
221        $this->statMinSeconds = $row['statMinSeconds'];
222        $this->statMaxSeconds = $row['statMaxSeconds'];
223        $this->recentBuysMaxHours = $row['recentBuysMaxHours'];
224        $this->buySurvey = $row['buySurvey'];
225        $this->transTexts = $row['transTexts'];
226        $this->enableWaitTime = $row['enableWaitTime'];
227        $this->drsApiKey = $row['drsApiKey'];
228        $this->surveySMSText = $row['surveySMSText'];
229        $this->postBuySMS = $row['postBuySMS'];
230        $this->active = $row['active'];
231        $this->wiwToken = $row['wiwToken'];
232        $this->wiwEnable = $row['wiwEnable'];
233        $this->wiwLocationID = $row['wiwLocationID'];
234        $this->homebaseApiKey = $row['homebaseApiKey'] ?? null;
235        $this->homebaseLocationId = $row['homebaseLocationId'] ?? null;
236        $this->homebaseEnable = $row['homebaseEnable'] ?? 0;
237        $this->schedulingProvider = $row['schedulingProvider'] ?? 'none';
238        $this->defaultOpenTime = $row['defaultOpenTime'] ?? '09:00';
239        $this->defaultCloseTime = $row['defaultCloseTime'] ?? '21:00';
240        $this->hoursLastUpdated = $row['hoursLastUpdated'] ?? null;
241        $this->hoursUpdatedByUserId = $row['hoursUpdatedByUserId'] ?? null;
242        $this->shopifyAPIKey = $row['shopifyAPIKey'];
243        $this->shopifyURL = $row['shopifyURL'];
244        $this->shopifyPassword = $row['shopifyPassword'];
245        $this->shopifyLocationID = $row['shopifyLocationID'];
246        $this->billingActive = $row['billingActive'];
247        $this->buyTextSMSType = $row['buyTextSMSType'];
248        $this->yellowTime = $row['yellowTime'];
249        $this->redTime = $row['redTime'];
250        $this->fiveStarsStoreID = $row['fiveStarsStoreID'];
251        $this->fiveStarsSoftwareID = $row['fiveStarsSoftwareID'];
252        $this->fiveStarsBuysIncluded = $row['fiveStarsBuysIncluded'];
253        $this->fiveStarsTaxIncluded = $row['fiveStarsTaxIncluded'];
254        $this->rcEnable = $row['rcEnable'];
255        $this->rcLine1 = $row['rcLine1'];
256        $this->rcLine2 = $row['rcLine2'];
257        $this->rcTagLine = $row['rcTagLine'];
258        $this->rcValidDays = $row['rcValidDays'];
259        $this->fiveStarsPointsRatio = $row['fiveStarsPointsRatio'];
260        $this->enableQueueSignIn = $row['enableQueueSignIn'];
261        $this->digitalSignType = $row['digitalSignType'];
262        $this->qbAccessToken = $row['qbAccessToken'];
263        $this->qbRefreshToken = $row['qbRefreshToken'];
264        $this->qbAccessTokenExpiration = $row['qbAccessTokenExpiration'];
265        $this->qbRefreshTokenExpiration = $row['qbRefreshTokenExpiration'];
266        $this->qbRealmID = $row['qbRealmID'];
267        $this->qbEnabled = $row['qbEnabled'] ?? 0;
268        $this->qbLastSync = $row['qbLastSync'] ?? null;
269        $this->billingType = $row['billingType'];
270        $this->nextBillingDate = $row['nextBillingDate'];
271        $this->billingRate = $row['billingRate'];
272        $this->billingDiscount = $row['billingDiscount'];
273        $this->billingDiscountDate = $row['billingDiscountDate'];
274        $this->dsWeatherBar = $row['dsWeatherBar'];
275        //$this->email = $row['email'];
276        //$this->automation = $row['automation'];
277        $this->setTextMessageService();
278    }
279
280    public function getLoyaltyConfig()
281    {
282        return null;
283
284    }
285    public function insert() {
286        global $db_name;
287        $db = dbConnectByName($db_name);
288
289        $stmt = $db->prepare("
290        INSERT INTO stores (
291            storeType, storeNum, dbName, address, city, state, zipcode, phone, timezone,
292            apiKey, smsType, smsKeyword, smsAccountID, smsPromoKeyword, smsPromoMessage, smsPromoID,
293            twilioPhone, ccAPI, ccToken, ccList, dev, waitTimeType, minutesPerContainer, requirePass,
294            referralSystem, loyaltySystem, estimateInterval, enableInterval, addSortersToEstimate,
295            statMinSeconds, statMaxSeconds, recentBuysMaxHours, buySurvey, email, automation, loyaltyConfig,
296            enableWaitTime, postBuySMS, drsApiKey, transTexts, active, buyTextSMSType, yellowTime, redTime,
297            enableQueueSignIn, fiveStarsStoreID, fiveStarsSoftwareID, fiveStarsTaxIncluded, fiveStarsBuysIncluded,
298            fiveStarsPointsRatio, rcEnable, rcLine1, rcLine2, rcTagLine, rcValidDays, wiwToken, wiwEnable,
299            wiwLocationID, shopifyAPIKey, shopifyURL, shopifyPassword, shopifyLocationID, qbAccessToken,
300            qbRefreshToken, qbAccessTokenExpiration, qbRefreshTokenExpiration, qbRealmID, billingActive,
301            billingType, nextBillingDate, billingRate, billingDiscount, billingDiscountDate, digitalSignType,
302            surveySMSText, typeNum
303        ) VALUES (
304            :storeType, :storeNum, :dbName, :address, :city, :state, :zipcode, :phone, :timezone,
305            :apiKey, :smsType, :smsKeyword, :smsAccountID, :smsPromoKeyword, :smsPromoMessage, :smsPromoID,
306            :twilioPhone, :ccAPI, :ccToken, :ccList, :dev, :waitTimeType, :minutesPerContainer, :requirePass,
307            :referralSystem, :loyaltySystem, :estimateInterval, :enableInterval, :addSortersToEstimate,
308            :statMinSeconds, :statMaxSeconds, :recentBuysMaxHours, :buySurvey, :email, :automation, :loyaltyConfig,
309            :enableWaitTime, :postBuySMS, :drsApiKey, :transTexts, :active, :buyTextSMSType, :yellowTime, :redTime,
310            :enableQueueSignIn, :fiveStarsStoreID, :fiveStarsSoftwareID, :fiveStarsTaxIncluded, :fiveStarsBuysIncluded,
311            :fiveStarsPointsRatio, :rcEnable, :rcLine1, :rcLine2, :rcTagLine, :rcValidDays, :wiwToken, :wiwEnable,
312            :wiwLocationID, :shopifyAPIKey, :shopifyURL, :shopifyPassword, :shopifyLocationID, :qbAccessToken,
313            :qbRefreshToken, :qbAccessTokenExpiration, :qbRefreshTokenExpiration, :qbRealmID, :billingActive,
314            :billingType, :nextBillingDate, :billingRate, :billingDiscount, :billingDiscountDate, :digitalSignType,
315            :surveySMSText, :typeNum
316        )
317    ");
318
319        $stmt->bindValue(':storeType', $this->getStoreType());
320        $stmt->bindValue(':storeNum', $this->getStoreNum());
321        $stmt->bindValue(':dbName', $this->getDbName());
322        $stmt->bindValue(':address', $this->getAddress());
323        $stmt->bindValue(':city', $this->getCity());
324        $stmt->bindValue(':state', $this->getState());
325        $stmt->bindValue(':zipcode', $this->getZipcode());
326        $stmt->bindValue(':phone', $this->getPhone());
327        $stmt->bindValue(':timezone', $this->getTimeZone());
328        $stmt->bindValue(':apiKey', $this->getApiKey());
329        $stmt->bindValue(':smsType', $this->getSmsType());
330        $stmt->bindValue(':smsKeyword', $this->getSmsKeyword());
331        $stmt->bindValue(':smsAccountID', $this->getSmsAccountID());
332        $stmt->bindValue(':smsPromoKeyword', $this->getSmsPromoKeyword());
333        $stmt->bindValue(':smsPromoMessage', $this->getSmsPromoMessage());
334        $stmt->bindValue(':smsPromoID', $this->getSmsPromoID());
335        $stmt->bindValue(':twilioPhone', $this->getTwilioPhone());
336        $stmt->bindValue(':ccAPI', $this->getCcAPI());
337        $stmt->bindValue(':ccToken', $this->getCcToken());
338        $stmt->bindValue(':ccList', $this->getCcList());
339        $stmt->bindValue(':dev', $this->getDev());
340        $stmt->bindValue(':waitTimeType', $this->getWaitTimeType());
341        $stmt->bindValue(':minutesPerContainer', $this->getMinutesPerContainer());
342        $stmt->bindValue(':requirePass', $this->getRequirePass());
343        $stmt->bindValue(':referralSystem', $this->getReferralSystem());
344        $stmt->bindValue(':loyaltySystem', $this->getLoyaltySystem());
345        $stmt->bindValue(':estimateInterval', $this->getEstimateInterval());
346        $stmt->bindValue(':enableInterval', $this->getEnableInterval());
347        $stmt->bindValue(':addSortersToEstimate', $this->getAddSortersToEstimate());
348        $stmt->bindValue(':statMinSeconds', $this->getStatMinSeconds());
349        $stmt->bindValue(':statMaxSeconds', $this->getStatMaxSeconds());
350        $stmt->bindValue(':recentBuysMaxHours', $this->getRecentBuysMaxHours());
351        $stmt->bindValue(':buySurvey', $this->getBuySurvey());
352        $stmt->bindValue(':email', $this->getEmail());
353        $stmt->bindValue(':automation', $this->getAutomation());
354        $stmt->bindValue(':loyaltyConfig', $this->getLoyaltyConfig());
355        $stmt->bindValue(':enableWaitTime', $this->getEnableWaitTime());
356        $stmt->bindValue(':postBuySMS', $this->getPostBuySMS());
357        $stmt->bindValue(':drsApiKey', $this->getDrsApiKey());
358        $stmt->bindValue(':transTexts', $this->getTransTexts());
359        $stmt->bindValue(':active', $this->getActive());
360        $stmt->bindValue(':buyTextSMSType', $this->getBuyTextSMSType());
361        $stmt->bindValue(':yellowTime', $this->getYellowTime());
362        $stmt->bindValue(':redTime', $this->getRedTime());
363        $stmt->bindValue(':enableQueueSignIn', $this->getEnableQueueSignIn());
364        $stmt->bindValue(':fiveStarsStoreID', $this->getFiveStarsStoreID());
365        $stmt->bindValue(':fiveStarsSoftwareID', $this->getFiveStarsSoftwareID());
366        $stmt->bindValue(':fiveStarsTaxIncluded', $this->getFiveStarsTaxIncluded());
367        $stmt->bindValue(':fiveStarsBuysIncluded', $this->getFiveStarsBuysIncluded());
368        $stmt->bindValue(':fiveStarsPointsRatio', $this->getFiveStarsPointsRatio());
369        $stmt->bindValue(':rcEnable', $this->getRcEnable());
370        $stmt->bindValue(':rcLine1', $this->getRcLine1());
371        $stmt->bindValue(':rcLine2', $this->getRcLine2());
372        $stmt->bindValue(':rcTagLine', $this->getRcTagLine());
373        $stmt->bindValue(':rcValidDays', $this->getRcValidDays());
374        $stmt->bindValue(':wiwToken', $this->getWiwToken());
375        $stmt->bindValue(':wiwEnable', $this->getWiwEnable());
376        $stmt->bindValue(':wiwLocationID', $this->getWiwLocationID());
377        $stmt->bindValue(':shopifyAPIKey', $this->getShopifyAPIKey());
378        $stmt->bindValue(':shopifyURL', $this->getShopifyURL());
379        $stmt->bindValue(':shopifyPassword', $this->getShopifyPassword());
380        $stmt->bindValue(':shopifyLocationID', $this->getShopifyLocationID());
381        $stmt->bindValue(':qbAccessToken', $this->getQbAccessToken());
382        $stmt->bindValue(':qbRefreshToken', $this->getQbRefreshToken());
383        $stmt->bindValue(':qbAccessTokenExpiration', $this->getQbAccessTokenExpiration());
384        $stmt->bindValue(':qbRefreshTokenExpiration', $this->getQbRefreshTokenExpiration());
385        $stmt->bindValue(':qbRealmID', $this->getQbRealmID());
386        $stmt->bindValue(':billingActive', $this->getBillingActive());
387        $stmt->bindValue(':billingType', $this->getBillingType());
388        $stmt->bindValue(':nextBillingDate', $this->getNextBillingDate());
389        $stmt->bindValue(':billingRate', $this->getBillingRate());
390        $stmt->bindValue(':billingDiscount', $this->getBillingDiscount());
391        $stmt->bindValue(':billingDiscountDate', $this->getBillingDiscountDate());
392        $stmt->bindValue(':digitalSignType', $this->getDigitalSignType());
393        $stmt->bindValue(':surveySMSText', $this->getSurveySMSText());
394        $stmt->bindValue(':typeNum', $this->getTypeNum());
395
396        return $stmt->execute();
397    }
398    public function update()
399    {
400        $db = dbConnectByName($_ENV['DB_NAME']);
401
402        $stmt = $db->prepare("
403        UPDATE stores SET
404            storeType = :storeType,
405            storeNum = :storeNum,
406            dbName = :dbName,
407            address = :address,
408            city = :city,
409            state = :state,
410            zipcode = :zipcode,
411            phone = :phone,
412            timezone = :timezone,
413            apiKey = :apiKey,
414            smsType = :smsType,
415            smsKeyword = :smsKeyword,
416            smsAccountID = :smsAccountID,
417            smsPromoKeyword = :smsPromoKeyword,
418            smsPromoMessage = :smsPromoMessage,
419            smsPromoID = :smsPromoID,
420            twilioPhone = :twilioPhone,
421            ccAPI = :ccAPI,
422            ccToken = :ccToken,
423            ccList = :ccList,
424            dev = :dev,
425            waitTimeType = :waitTimeType,
426            minutesPerContainer = :minutesPerContainer,
427            requirePass = :requirePass,
428            referralSystem = :referralSystem,
429            loyaltySystem = :loyaltySystem,
430            estimateInterval = :estimateInterval,
431            enableInterval = :enableInterval,
432            addSortersToEstimate = :addSortersToEstimate,
433            statMinSeconds = :statMinSeconds,
434            statMaxSeconds = :statMaxSeconds,
435            recentBuysMaxHours = :recentBuysMaxHours,
436            buySurvey = :buySurvey,
437            email = :email,
438            automation = :automation,
439            loyaltyConfig = :loyaltyConfig,
440            enableWaitTime = :enableWaitTime,
441            postBuySMS = :postBuySMS,
442            drsApiKey = :drsApiKey,
443            transTexts = :transTexts,
444            active = :active,
445            buyTextSMSType = :buyTextSMSType,
446            yellowTime = :yellowTime,
447            redTime = :redTime,
448            enableQueueSignIn = :enableQueueSignIn,
449            fiveStarsStoreID = :fiveStarsStoreID,
450            fiveStarsSoftwareID = :fiveStarsSoftwareID,
451            fiveStarsTaxIncluded = :fiveStarsTaxIncluded,
452            fiveStarsBuysIncluded = :fiveStarsBuysIncluded,
453            fiveStarsPointsRatio = :fiveStarsPointsRatio,
454            rcEnable = :rcEnable,
455            rcLine1 = :rcLine1,
456            rcLine2 = :rcLine2,
457            rcTagLine = :rcTagLine,
458            rcValidDays = :rcValidDays,
459            wiwToken = :wiwToken,
460            wiwEnable = :wiwEnable,
461            wiwLocationID = :wiwLocationID,
462            shopifyAPIKey = :shopifyAPIKey,
463            shopifyURL = :shopifyURL,
464            shopifyPassword = :shopifyPassword,
465            shopifyLocationID = :shopifyLocationID,
466            qbAccessToken = :qbAccessToken,
467            qbRefreshToken = :qbRefreshToken,
468            qbAccessTokenExpiration = :qbAccessTokenExpiration,
469            qbRefreshTokenExpiration = :qbRefreshTokenExpiration,
470            qbRealmID = :qbRealmID,
471            billingActive = :billingActive,
472            billingType = :billingType,
473            nextBillingDate = :nextBillingDate,
474            billingRate = :billingRate,
475            billingDiscount = :billingDiscount,
476            billingDiscountDate = :billingDiscountDate,
477            digitalSignType = :digitalSignType,
478            dsWeatherBar = :dsWeatherBar,
479            surveySMSText = :surveySMSText
480        WHERE typeNum = :typeNum
481    ");
482
483        $stmt->bindValue(':storeType', $this->getStoreType());
484        $stmt->bindValue(':storeNum', $this->getStoreNum());
485        $stmt->bindValue(':dbName', $this->getDbName());
486        $stmt->bindValue(':address', $this->getAddress());
487        $stmt->bindValue(':city', $this->getCity());
488        $stmt->bindValue(':state', $this->getState());
489        $stmt->bindValue(':zipcode', $this->getZipcode());
490        $stmt->bindValue(':phone', $this->getPhone());
491        $stmt->bindValue(':timezone', $this->getTimeZone());
492        $stmt->bindValue(':apiKey', $this->getApiKey());
493        $stmt->bindValue(':smsType', $this->getSmsType());
494        $stmt->bindValue(':smsKeyword', $this->getSmsKeyword());
495        $stmt->bindValue(':smsAccountID', $this->getSmsAccountID());
496        $stmt->bindValue(':smsPromoKeyword', $this->getSmsPromoKeyword());
497        $stmt->bindValue(':smsPromoMessage', $this->getSmsPromoMessage());
498        $stmt->bindValue(':smsPromoID', $this->getSmsPromoID());
499        $stmt->bindValue(':twilioPhone', $this->getTwilioPhone());
500        $stmt->bindValue(':ccAPI', $this->getCcAPI());
501        $stmt->bindValue(':ccToken', $this->getCcToken());
502        $stmt->bindValue(':ccList', $this->getCcList());
503        $stmt->bindValue(':dev', $this->getDev());
504        $stmt->bindValue(':waitTimeType', $this->getWaitTimeType());
505        $stmt->bindValue(':minutesPerContainer', $this->getMinutesPerContainer());
506        $stmt->bindValue(':requirePass', $this->getRequirePass());
507        $stmt->bindValue(':referralSystem', $this->getReferralSystem());
508        $stmt->bindValue(':loyaltySystem', $this->getLoyaltySystem());
509        $stmt->bindValue(':estimateInterval', $this->getEstimateInterval());
510        $stmt->bindValue(':enableInterval', $this->getEnableInterval());
511        $stmt->bindValue(':addSortersToEstimate', $this->getAddSortersToEstimate());
512        $stmt->bindValue(':statMinSeconds', $this->getStatMinSeconds());
513        $stmt->bindValue(':statMaxSeconds', $this->getStatMaxSeconds());
514        $stmt->bindValue(':recentBuysMaxHours', $this->getRecentBuysMaxHours());
515        $stmt->bindValue(':buySurvey', $this->getBuySurvey());
516        $stmt->bindValue(':email', $this->getEmail());
517        $stmt->bindValue(':automation', $this->getAutomation());
518        $stmt->bindValue(':loyaltyConfig', $this->getLoyaltyConfig());
519        $stmt->bindValue(':enableWaitTime', $this->getEnableWaitTime());
520        $stmt->bindValue(':postBuySMS', $this->getPostBuySMS());
521        $stmt->bindValue(':drsApiKey', $this->getDrsApiKey());
522        $stmt->bindValue(':transTexts', $this->getTransTexts());
523        $stmt->bindValue(':active', $this->getActive());
524        $stmt->bindValue(':buyTextSMSType', $this->getBuyTextSMSType());
525        $stmt->bindValue(':yellowTime', $this->getYellowTime());
526        $stmt->bindValue(':redTime', $this->getRedTime());
527        $stmt->bindValue(':enableQueueSignIn', $this->getEnableQueueSignIn());
528        $stmt->bindValue(':fiveStarsStoreID', $this->getFiveStarsStoreID());
529        $stmt->bindValue(':fiveStarsSoftwareID', $this->getFiveStarsSoftwareID());
530        $stmt->bindValue(':fiveStarsTaxIncluded', $this->getFiveStarsTaxIncluded());
531        $stmt->bindValue(':fiveStarsBuysIncluded', $this->getFiveStarsBuysIncluded());
532        $stmt->bindValue(':fiveStarsPointsRatio', $this->getFiveStarsPointsRatio());
533        $stmt->bindValue(':rcEnable', $this->getRcEnable());
534        $stmt->bindValue(':rcLine1', $this->getRcLine1());
535        $stmt->bindValue(':rcLine2', $this->getRcLine2());
536        $stmt->bindValue(':rcTagLine', $this->getRcTagLine());
537        $stmt->bindValue(':rcValidDays', $this->getRcValidDays());
538        $stmt->bindValue(':wiwToken', $this->getWiwToken());
539        $stmt->bindValue(':wiwEnable', $this->getWiwEnable());
540        $stmt->bindValue(':wiwLocationID', $this->getWiwLocationID());
541        $stmt->bindValue(':shopifyAPIKey', $this->getShopifyAPIKey());
542        $stmt->bindValue(':shopifyURL', $this->getShopifyURL());
543        $stmt->bindValue(':shopifyPassword', $this->getShopifyPassword());
544        $stmt->bindValue(':shopifyLocationID', $this->getShopifyLocationID());
545        $stmt->bindValue(':qbAccessToken', $this->getQbAccessToken());
546        $stmt->bindValue(':qbRefreshToken', $this->getQbRefreshToken());
547        $stmt->bindValue(':qbAccessTokenExpiration', $this->getQbAccessTokenExpiration());
548        $stmt->bindValue(':qbRefreshTokenExpiration', $this->getQbRefreshTokenExpiration());
549        $stmt->bindValue(':qbRealmID', $this->getQbRealmID());
550        $stmt->bindValue(':billingActive', $this->getBillingActive());
551        $stmt->bindValue(':billingType', $this->getBillingType());
552        $stmt->bindValue(':nextBillingDate', $this->getNextBillingDate());
553        $stmt->bindValue(':billingRate', $this->getBillingRate());
554        $stmt->bindValue(':billingDiscount', $this->getBillingDiscount());
555        $stmt->bindValue(':billingDiscountDate', $this->getBillingDiscountDate());
556        $stmt->bindValue(':digitalSignType', $this->getDigitalSignType());
557        $stmt->bindValue(":dsWeatherBar", $this->dsWeatherBar);
558        $stmt->bindValue(':surveySMSText', $this->getSurveySMSText());
559        $stmt->bindValue(':typeNum', $this->getTypeNum());
560
561        return $stmt->execute();
562    }
563
564    public function getCompanyName()
565    {
566        switch ((int)$this->getStoreType()) {
567            case 0:
568                return "Clothes Mentor";
569                break;
570            case 1:
571                return "Plato's Closet";
572                break;
573            case 2:
574                return "Once Upon a Child";
575                break;
576            case 3:
577                return "Style Encore";
578                break;
579            case 4:
580                return "Play it Again Sports";
581                break;
582            default:
583                return "Unknown";
584                break;
585        }
586
587
588    }
589
590    public function getLoyaltyGroup()
591    {
592        return null;
593    }
594
595    public function getUnusedInstallKey()
596    {
597        global $db_name;
598        $db = dbConnectByName($db_name);
599        $stmt = $db->prepare("SELECT * FROM installKeys WHERE typeNum = :typeNum AND used = 0");
600        $stmt->bindValue(":typeNum", $this->typeNum);
601        $stmt->execute();
602        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
603        if ($row && isset($row['id']) && $row['id'] > 0) {
604            $row['key'] = substr(chunk_split($row['key'], 4, '-'), 0, -1);
605            return $row;
606        } else {
607            return null;
608        }
609    }
610
611    public function updateWiwToken()
612    {
613        global $db_name;
614        $db = dbConnectByName($db_name);
615        $stmt = $db->prepare("UPDATE stores SET `wiwToken` = :token WHERE typeNum = :typeNum");
616        $stmt->bindValue(":token", $this->wiwToken);
617        $stmt->bindValue(":typeNum", $this->typeNum);
618        if ($stmt->execute()) {
619            return true;
620        }
621        error_log("Error updating wiw token for store " . $this->typeNum . " " . $stmt->errorInfo()[2]);
622        return false;
623    }
624
625    public function updateQbAccessToken()
626    {
627        global $db_name;
628        $db = dbConnectByName($db_name);
629        $db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
630        $db->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
631        $stmt = $db->prepare("UPDATE stores SET qbAccessToken = :token, qbAccessTokenExpiration = :expiration, qbRealmID = :realmID WHERE typeNum = :typeNum");
632        $stmt->bindValue(":token", $this->qbAccessToken);
633        $stmt->bindValue(":expiration", $this->qbAccessTokenExpiration);
634        $stmt->bindValue(":typeNum", $this->typeNum);
635        $stmt->bindValue(":realmID", $this->qbRealmID);
636        if ($stmt->execute()) {
637            error_log("Updated QB Access Token for store " . $this->typeNum);
638            return true;
639        }
640        return false;
641    }
642
643    public function updateQbRefreshToken()
644    {
645        global $db_name;
646        $db = dbConnectByName($db_name);
647        $stmt = $db->prepare("UPDATE stores SET `qbRefreshToken` = :token, `qbRefreshTokenExpiration` = :expiration WHERE typeNum = :typeNum");
648        $stmt->bindValue(":token", $this->qbRefreshToken);
649        $stmt->bindValue(":expiration", $this->qbRefreshTokenExpiration);
650        $stmt->bindValue(":typeNum", $this->typeNum);
651        if ($stmt->execute()) {
652            return true;
653        }
654        return false;
655    }
656
657    public function updateBillingActive()
658    {
659        global $db_name;
660        $db = dbConnectByName($db_name);
661        $stmt = $db->prepare("UPDATE stores SET `billingActive` = :billingActive WHERE typeNum = :typeNum");
662        $stmt->bindValue(":billingActive", $this->getBillingActive());
663        $stmt->bindValue(":typeNum", $this->typeNum);
664        if ($stmt->execute()) {
665            return true;
666        }
667        return false;
668    }
669
670    public function updateWiwLocationID()
671    {
672        global $db_name;
673        $db = dbConnectByName($db_name);
674        $stmt = $db->prepare("UPDATE stores SET `wiwLocationID` = :locationID WHERE typeNum = :typeNum");
675        $stmt->bindValue(":locationID", $this->wiwLocationID);
676        $stmt->bindValue(":typeNum", $this->typeNum);
677        if ($stmt->execute()) {
678            return true;
679        }
680        return false;
681    }
682
683    public function enableWiw()
684    {
685        global $db_name;
686        $db = dbConnectByName($db_name);
687        $stmt = $db->prepare("UPDATE stores SET `wiwEnable` = 1 WHERE typeNum = :typeNum");
688        $stmt->bindValue(":typeNum", $this->typeNum);
689        if ($stmt->execute()) {
690            return true;
691        }
692        return false;
693    }
694
695    public function getAllMassSMS()
696    {
697        global $db_name;
698        $db = dbConnectByName($db_name);
699        $smsArray = [];
700        try {
701            $stmt = $db->prepare("SELECT * FROM loyaltyMassSMS WHERE typeNum = :typeNum ORDER BY id DESC");
702            $stmt->bindValue(":typeNum", $this->typeNum);
703            $stmt->execute();
704            while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
705
706
707                $message = new \LoyaltySMSMessage(null, $this->typeNum, $row['messageID']);
708                $row['message'] = $message;
709
710                if ($row['couponID'] !== null) {
711                    $coupon = new \LoyaltyCoupon(null, $this->typeNum, $row['couponID']);
712                    $row['coupon'] = $coupon;
713                }
714
715                if ($row['processed'] == 1) {
716                    $stmt2 = $db->prepare("SELECT SUM(IF(sendError = 0, 1,0)) as totalCustomersSent, SUM(IF(messagesSent > 0, messagesSent,0)) as totalMessagesSent, COUNT(*) as totalScheduled, SUM(IF(sendError = 99, 1,0)) as totalErrorRateLimited, SUM(IF(sendError = 97, 1,0)) as totalErrorOptedOut, SUM(IF(sendError = 98, 1,0)) as totalErrorDNTList, SUM(IF(delivered = 1, messagesSent,0)) as totalDelivered FROM (SELECT * FROM loyaltyOutgoing WHERE massSMSID = :id) as A
717");
718                    $stmt2->bindValue(":id", $row['id']);
719                    $stmt2->execute();
720                    $row2 = $stmt2->fetch(\PDO::FETCH_ASSOC);
721                    $row['totalDelivered'] = $row2['totalDelivered'];
722                    $row['totalScheduled'] = $row2['totalScheduled'];
723                    $row['totalCustomersSent'] = $row2['totalCustomersSent'];
724                    $row['totalMessagesSent'] = $row2['totalMessagesSent'];
725                    $row['totalErrorRateLimited'] = $row2['totalErrorRateLimited'];
726                    $row['totalErrorOptedOut'] = $row2['totalErrorOptedOut'];
727                    $row['totalErrorDNTList'] = $row2['totalErrorDNTList'];
728                } else {
729                    $row['totalDelivered'] = 0;
730                    $row['totalCustomersSent'] = 0;
731                    $row['totalMessagesSent'] = 0;
732                    $row['totalDelivered'] = 0;
733                    $row['totalScheduled'] = 0;
734                    $row['totalSent'] = 0;
735                    $row['totalErrorRateLimited'] = 0;
736                    $row['totalErrorOptedOut'] = 0;
737                    $row['totalErrorDNTList'] = 0;
738                }
739                $smsArray[] = $row;
740            }
741            return $smsArray;
742        } catch (\PDOException $e) {
743
744        }
745        return NULL;
746
747    }
748
749    public function getOptTotals()
750    {
751        global $db_name;
752        $db = dbConnectByName($db_name);
753        try {
754            $stmt = $db->prepare("SELECT 
755(SELECT count(DISTINCT(loyaltyID)) as totalCustomers FROM loyaltyData JOIN loyaltyCustomers ON loyaltyData.loyaltyID = loyaltyCustomers.id WHERE loyaltyCustomers.optValue = 0 AND loyaltyData.type IN(1,2,3) AND loyaltyData.typeNum = :typeNum) as totalCustomers,
756(SELECT count(DISTINCT(loyaltyID)) as totalOptIn FROM loyaltyData JOIN loyaltyCustomers ON loyaltyData.loyaltyID = loyaltyCustomers.id WHERE loyaltyCustomers.optValue = 1 AND loyaltyData.type IN(1,2,3) AND loyaltyData.typeNum = :typeNum) as totalActive,
757(SELECT count(*) as totalOptOuts FROM loyaltyDoNotTextList INNER JOIN 
758(SELECT DISTINCT loyaltyCustomers.phone FROM loyaltyData JOIN loyaltyCustomers ON loyaltyData.loyaltyID = loyaltyCustomers.id WHERE loyaltyData.type IN(1,2,3) AND loyaltyData.typeNum = :typeNum) as loyaltyCustomers 
759ON loyaltyCustomers.phone collate utf8_general_ci = loyaltyDoNotTextList.phone collate utf8_general_ci  ) as totalOptOuts");
760            $stmt->bindValue(":typeNum", $this->getTypeNum());
761            $stmt->execute();
762            $row = $stmt->fetch(\PDO::FETCH_ASSOC);
763            return array("totalList" => $row['totalCustomers'], "optedIn" => $row['totalActive'], "optedOut" => $row['totalOptOuts'], "awaitingOptIn" => (int)$row['totalCustomers'] - (int)$row['totalOptOuts'] - (int)$row['totalActive']);
764        } catch (\PDOException $e) {
765
766        }
767        return NULL;
768
769    }
770
771    public function setDev($dev)
772    {
773        $this->dev = $dev;
774    }
775
776    public function getDev()
777    {
778        return $this->dev;
779    }
780
781    public function setCcList($ccList)
782    {
783        $this->ccList = $ccList;
784    }
785
786    public function getCcList()
787    {
788        return $this->ccList;
789    }
790
791    public function setSmsPromoID($smsPromoID)
792    {
793        $this->smsPromoID = $smsPromoID;
794    }
795
796    public function getSmsPromoID()
797    {
798        return $this->smsPromoID;
799    }
800
801    public function setSmsPromoKeyword($smsPromoKeyword)
802    {
803        $this->smsPromoKeyword = $smsPromoKeyword;
804    }
805
806    public function getSmsPromoKeyword()
807    {
808        return $this->smsPromoKeyword;
809    }
810
811    public function setStoreNum($storeNum)
812    {
813        $this->storeNum = $storeNum;
814    }
815
816    public function getStoreNum()
817    {
818        return $this->storeNum;
819    }
820
821    public function setStoreType($storeType)
822    {
823        $this->storeType = $storeType;
824    }
825
826    public function getStoreType()
827    {
828        return $this->storeType;
829    }
830
831    public function setTypeNum($typeNum)
832    {
833        $this->typeNum = $typeNum;
834    }
835
836    public function getTypeNum()
837    {
838        return $this->typeNum;
839    }
840
841    public function setAddress($address)
842    {
843        $this->address = $address;
844    }
845
846    public function getAddress()
847    {
848        return $this->address;
849    }
850
851
852    public function setApiKey($apiKey)
853    {
854        $this->apiKey = $apiKey;
855    }
856
857    public function getApiKey()
858    {
859        return $this->apiKey;
860    }
861
862    public function setCcAPI($ccAPI)
863    {
864        $this->ccAPI = $ccAPI;
865    }
866
867    public function getCcAPI()
868    {
869        return $this->ccAPI;
870    }
871
872    public function setCcToken($ccToken)
873    {
874        $this->ccToken = $ccToken;
875    }
876
877    public function getCcToken()
878    {
879        return $this->ccToken;
880    }
881
882    /**
883     * @return string|null
884     */
885    public function getCcRefreshToken()
886    {
887        return $this->ccRefreshToken;
888    }
889
890    /**
891     * @param string|null $ccRefreshToken
892     */
893    public function setCcRefreshToken($ccRefreshToken)
894    {
895        $this->ccRefreshToken = $ccRefreshToken;
896    }
897
898    /**
899     * @return string|null
900     */
901    public function getCcTokenExpiration()
902    {
903        return $this->ccTokenExpiration;
904    }
905
906    /**
907     * @param string|null $ccTokenExpiration
908     */
909    public function setCcTokenExpiration($ccTokenExpiration)
910    {
911        $this->ccTokenExpiration = $ccTokenExpiration;
912    }
913
914    /**
915     * @return int
916     */
917    public function getCcEnabled()
918    {
919        return $this->ccEnabled;
920    }
921
922    /**
923     * @param int $ccEnabled
924     */
925    public function setCcEnabled($ccEnabled)
926    {
927        $this->ccEnabled = $ccEnabled;
928    }
929
930    /**
931     * Update Constant Contact OAuth tokens in database
932     * @return bool
933     */
934    public function updateCcTokens()
935    {
936        global $db_name;
937        $db = dbConnectByName($db_name);
938        $stmt = $db->prepare("UPDATE stores SET
939            ccToken = :token,
940            ccRefreshToken = :refreshToken,
941            ccTokenExpiration = :expiration,
942            ccEnabled = :enabled
943            WHERE typeNum = :typeNum");
944        $stmt->bindValue(":token", $this->ccToken);
945        $stmt->bindValue(":refreshToken", $this->ccRefreshToken);
946        $stmt->bindValue(":expiration", $this->ccTokenExpiration);
947        $stmt->bindValue(":enabled", $this->ccEnabled);
948        $stmt->bindValue(":typeNum", $this->typeNum);
949        if ($stmt->execute()) {
950            return true;
951        }
952        error_log("Error updating CC tokens for store " . $this->typeNum . " " . $stmt->errorInfo()[2]);
953        return false;
954    }
955
956    /**
957     * Update Constant Contact list selection in database
958     * @return bool
959     */
960    public function updateCcList()
961    {
962        global $db_name;
963        $db = dbConnectByName($db_name);
964        $stmt = $db->prepare("UPDATE stores SET ccList = :list WHERE typeNum = :typeNum");
965        $stmt->bindValue(":list", $this->ccList);
966        $stmt->bindValue(":typeNum", $this->typeNum);
967        if ($stmt->execute()) {
968            return true;
969        }
970        error_log("Error updating CC list for store " . $this->typeNum . " " . $stmt->errorInfo()[2]);
971        return false;
972    }
973
974    /**
975     * Disconnect Constant Contact (clear all CC data)
976     * @return bool
977     */
978    public function disconnectCc()
979    {
980        global $db_name;
981        $db = dbConnectByName($db_name);
982        $stmt = $db->prepare("UPDATE stores SET
983            ccToken = NULL,
984            ccRefreshToken = NULL,
985            ccTokenExpiration = NULL,
986            ccEnabled = 0,
987            ccList = NULL
988            WHERE typeNum = :typeNum");
989        $stmt->bindValue(":typeNum", $this->typeNum);
990        if ($stmt->execute()) {
991            $this->ccToken = null;
992            $this->ccRefreshToken = null;
993            $this->ccTokenExpiration = null;
994            $this->ccEnabled = 0;
995            $this->ccList = null;
996            return true;
997        }
998        error_log("Error disconnecting CC for store " . $this->typeNum . " " . $stmt->errorInfo()[2]);
999        return false;
1000    }
1001
1002    /**
1003     * Check if Constant Contact is connected
1004     * @return bool
1005     */
1006    public function isCcConnected()
1007    {
1008        return !empty($this->ccToken) && !empty($this->ccRefreshToken);
1009    }
1010
1011    public function setCity($city)
1012    {
1013        $this->city = $city;
1014    }
1015
1016    public function getCity()
1017    {
1018        return $this->city;
1019    }
1020
1021    public function setDbName($dbName)
1022    {
1023        $this->dbName = $dbName;
1024    }
1025
1026    public function getDbName()
1027    {
1028        return $this->dbName;
1029    }
1030
1031    public function setId($id)
1032    {
1033        $this->id = $id;
1034    }
1035
1036    public function getId()
1037    {
1038        return $this->id;
1039    }
1040
1041    public function setPhone($phone)
1042    {
1043        $this->phone = $phone;
1044    }
1045
1046    public function getPhone()
1047    {
1048        return $this->phone;
1049    }
1050
1051    public function setSmsAccountID($smsAccountID)
1052    {
1053        $this->smsAccountID = $smsAccountID;
1054    }
1055
1056    public function getSmsAccountID()
1057    {
1058        return $this->smsAccountID;
1059    }
1060
1061    public function setSmsKeyword($smsKeyword)
1062    {
1063        $this->smsKeyword = $smsKeyword;
1064    }
1065
1066    public function getSmsKeyword()
1067    {
1068        return $this->smsKeyword;
1069    }
1070
1071    public function setState($state)
1072    {
1073        $this->state = $state;
1074    }
1075
1076    public function getState()
1077    {
1078        return $this->state;
1079    }
1080
1081    public function setTimeZone($timeZone)
1082    {
1083        $this->timezone = $timeZone;
1084    }
1085
1086    public function getTimeZone()
1087    {
1088        return $this->timezone;
1089    }
1090
1091    public function setType($type)
1092    {
1093        $this->type = $type;
1094    }
1095
1096    public function getType()
1097    {
1098        return $this->type;
1099    }
1100
1101    public function setZipcode($zipcode)
1102    {
1103        $this->zipcode = $zipcode;
1104    }
1105
1106    public function getZipcode()
1107    {
1108        return $this->zipcode;
1109    }
1110
1111    public function setMinutesPerContainer($minutesPerContainer)
1112    {
1113        $this->minutesPerContainer = $minutesPerContainer;
1114    }
1115
1116    public function getMinutesPerContainer()
1117    {
1118        return $this->minutesPerContainer;
1119    }
1120
1121    public function setWaitTimeType($waitTimeType)
1122    {
1123        $this->waitTimeType = $waitTimeType;
1124    }
1125
1126    public function getWaitTimeType()
1127    {
1128        return $this->waitTimeType;
1129    }
1130
1131    public function setTwilioPhone($twilioPhone)
1132    {
1133        $this->twilioPhone = $twilioPhone;
1134    }
1135
1136    public function getTwilioPhone()
1137    {
1138        return $this->twilioPhone;
1139    }
1140
1141    public function setSmsType($smsType)
1142    {
1143        $this->smsType = $smsType;
1144    }
1145
1146    public function getSmsType()
1147    {
1148        return $this->smsType;
1149    }
1150
1151    public function setSmsPromoMessage($smsPromoMessage)
1152    {
1153        $this->smsPromoMessage = $smsPromoMessage;
1154    }
1155
1156    public function getSmsPromoMessage()
1157    {
1158        return $this->smsPromoMessage;
1159    }
1160
1161    public function setRequirePass($requirePass)
1162    {
1163        $this->requirePass = $requirePass;
1164    }
1165
1166    public function getRequirePass()
1167    {
1168        return $this->requirePass;
1169    }
1170
1171    /**
1172     * @param mixed $referralSystem
1173     */
1174    public function setReferralSystem($referralSystem)
1175    {
1176        $this->referralSystem = $referralSystem;
1177    }
1178
1179    /**
1180     * @return mixed
1181     */
1182    public function getReferralSystem()
1183    {
1184        return $this->referralSystem;
1185    }
1186
1187    /**
1188     * @return mixed
1189     */
1190    public function getEstimateInterval()
1191    {
1192        return $this->estimateInterval;
1193    }
1194
1195    /**
1196     * @param mixed $estimateInterval
1197     */
1198    public function setEstimateInterval($estimateInterval)
1199    {
1200        $this->estimateInterval = $estimateInterval;
1201    }
1202
1203    /**
1204     * @return mixed
1205     */
1206    public function getEnableInterval()
1207    {
1208        return $this->enableInterval;
1209    }
1210
1211    /**
1212     * @param mixed $enableInterval
1213     */
1214    public function setEnableInterval($enableInterval)
1215    {
1216        $this->enableInterval = $enableInterval;
1217    }
1218
1219    /**
1220     * @return mixed
1221     */
1222    public function getAddSortersToEstimate()
1223    {
1224        return $this->addSortersToEstimate;
1225    }
1226
1227    /**
1228     * @param mixed $addSortersToEstimate
1229     */
1230    public function setAddSortersToEstimate($addSortersToEstimate)
1231    {
1232        $this->addSortersToEstimate = $addSortersToEstimate;
1233    }
1234
1235    /**
1236     * @return mixed
1237     */
1238    public function getStatMinSeconds()
1239    {
1240        return $this->statMinSeconds;
1241    }
1242
1243    /**
1244     * @param mixed $statMinimumSeconds
1245     */
1246    public function setStatMinSeconds($statMinSeconds)
1247    {
1248        $this->statMinSeconds = $statMinSeconds;
1249    }
1250
1251    /**
1252     * @return mixed
1253     */
1254    public function getStatMaxSeconds()
1255    {
1256        return $this->statMaxSeconds;
1257    }
1258
1259    /**
1260     * @param mixed $statMaxSeconds
1261     */
1262    public function setStatMaxSeconds($statMaxSeconds)
1263    {
1264        $this->statMaxSeconds = $statMaxSeconds;
1265    }
1266
1267    /**
1268     * @return mixed
1269     */
1270    public function getRecentBuysMaxHours()
1271    {
1272        return $this->recentBuysMaxHours;
1273    }
1274
1275    /**
1276     * @param mixed $recentBuysMaxHours
1277     */
1278    public function setRecentBuysMaxHours($recentBuysMaxHours)
1279    {
1280        $this->recentBuysMaxHours = $recentBuysMaxHours;
1281    }
1282
1283    /**
1284     * @return mixed
1285     */
1286    public function getLoyaltySystem()
1287    {
1288        return $this->loyaltySystem;
1289    }
1290
1291    /**
1292     * @param mixed $loyaltySystem
1293     */
1294    public function setLoyaltySystem($loyaltySystem)
1295    {
1296        $this->loyaltySystem = $loyaltySystem;
1297    }
1298
1299    /**
1300     * @return mixed
1301     */
1302    public function getBuySurvey()
1303    {
1304        return $this->buySurvey;
1305    }
1306
1307    /**
1308     * @param mixed $buySurvey
1309     */
1310    public function setBuySurvey($buySurvey)
1311    {
1312        $this->buySurvey = $buySurvey;
1313    }
1314
1315    /**
1316     * @return mixed
1317     */
1318    public function getRcEnable()
1319    {
1320        return $this->rcEnable;
1321    }
1322
1323    /**
1324     * @param mixed $rcEnable
1325     */
1326    public function setRcEnable($rcEnable)
1327    {
1328        $this->rcEnable = $rcEnable;
1329    }
1330
1331    /**
1332     * @return mixed
1333     */
1334    public function getRcLine1()
1335    {
1336        return $this->rcLine1;
1337    }
1338
1339    /**
1340     * @param mixed $rcLine1
1341     */
1342    public function setRcLine1($rcLine1)
1343    {
1344        $this->rcLine1 = $rcLine1;
1345    }
1346
1347    /**
1348     * @return mixed
1349     */
1350    public function getRcLine2()
1351    {
1352        return $this->rcLine2;
1353    }
1354
1355    /**
1356     * @param mixed $rcLine2
1357     */
1358    public function setRcLine2($rcLine2)
1359    {
1360        $this->rcLine2 = $rcLine2;
1361    }
1362
1363    /**
1364     * @return mixed
1365     */
1366    public function getRcTagLine()
1367    {
1368        return $this->rcTagLine;
1369    }
1370
1371    /**
1372     * @param mixed $rcTagLine
1373     */
1374    public function setRcTagLine($rcTagLine)
1375    {
1376        $this->rcTagLine = $rcTagLine;
1377    }
1378
1379    /**
1380     * @return mixed
1381     */
1382    public function getRcValidDays()
1383    {
1384        return $this->rcValidDays;
1385    }
1386
1387    /**
1388     * @param mixed $rcValidDays
1389     */
1390    public function setRcValidDays($rcValidDays)
1391    {
1392        $this->rcValidDays = $rcValidDays;
1393    }
1394
1395    /**
1396     * @return mixed
1397     */
1398    public function getTransTexts()
1399    {
1400        return $this->transTexts;
1401    }
1402
1403    /**
1404     * @param mixed $transTexts
1405     */
1406    public function setTransTexts($transTexts)
1407    {
1408        $this->transTexts = $transTexts;
1409    }
1410
1411    /**
1412     * @return mixed
1413     */
1414    public function getEmail()
1415    {
1416        return $this->email;
1417    }
1418
1419    /**
1420     * @param mixed $email
1421     */
1422    public function setEmail($email)
1423    {
1424        $this->email = $email;
1425    }
1426
1427    /**
1428     * @return mixed
1429     */
1430    public function getAutomation()
1431    {
1432        return $this->automation;
1433    }
1434
1435    /**
1436     * @param mixed $automation
1437     */
1438    public function setAutomation($automation)
1439    {
1440        $this->automation = $automation;
1441    }
1442
1443    /**
1444     * @return mixed
1445     */
1446    public function getDb()
1447    {
1448        return $this->db;
1449    }
1450
1451    /**
1452     * @param mixed $db
1453     */
1454    public function setDb($db)
1455    {
1456        $this->db = $db;
1457    }
1458
1459    /**
1460     * @return mixed
1461     */
1462    public function getEnableWaitTime()
1463    {
1464        return $this->enableWaitTime;
1465    }
1466
1467    /**
1468     * @param mixed $enableWaitTime
1469     */
1470    public function setEnableWaitTime($enableWaitTime)
1471    {
1472        $this->enableWaitTime = $enableWaitTime;
1473    }
1474
1475    /**
1476     * @return mixed
1477     */
1478    public function getDrsApiKey()
1479    {
1480        return $this->drsApiKey;
1481    }
1482
1483    /**
1484     * @param mixed $drsApiKey
1485     */
1486    public function setDrsApiKey($drsApiKey)
1487    {
1488        $this->drsApiKey = $drsApiKey;
1489    }
1490
1491    public function getSurveySMSText()
1492    {
1493        return $this->surveySMSText;
1494    }
1495
1496    /**
1497     * @param mixed $surveySMSText
1498     */
1499    public function setSurveySMSText($surveySMSText)
1500    {
1501        $this->surveySMSText = $surveySMSText;
1502    }
1503
1504    /**
1505     * @return mixed
1506     */
1507    public function getWiwToken()
1508    {
1509        return $this->wiwToken;
1510    }
1511
1512    /**
1513     * @param mixed $wiw_token
1514     */
1515    public function setWiwToken($wiw_token)
1516    {
1517        $this->wiwToken = $wiw_token;
1518    }
1519
1520    /**
1521     * @return mixed
1522     */
1523    public function getWiwEnable()
1524    {
1525        return $this->wiwEnable;
1526    }
1527
1528    /**
1529     * @param mixed $wiwEnable
1530     */
1531    public function setWiwEnable($wiwEnable)
1532    {
1533        $this->wiwEnable = $wiwEnable;
1534    }
1535
1536    /**
1537     * @return mixed
1538     */
1539    public function getWiwLocationID()
1540    {
1541        return $this->wiwLocationID;
1542    }
1543
1544    /**
1545     * @param mixed $wiwLocationID
1546     */
1547    public function setWiwLocationID($wiwLocationID)
1548    {
1549        $this->wiwLocationID = $wiwLocationID;
1550    }
1551
1552
1553    /**
1554     * @return mixed
1555     */
1556    public function getPostBuySMS()
1557    {
1558        return $this->postBuySMS;
1559    }
1560
1561    /**
1562     * @param mixed $enablePostBuySMS
1563     */
1564    public function setPostBuySMS($enablePostBuySMS)
1565    {
1566        $this->postBuySMS = $enablePostBuySMS;
1567    }
1568
1569    /**
1570     * @return mixed
1571     */
1572    public function getActive()
1573    {
1574        return $this->active;
1575    }
1576
1577    /**
1578     * @param mixed $active
1579     */
1580    public function setActive($active)
1581    {
1582        $this->active = $active;
1583    }
1584
1585    /**
1586     * @return mixed
1587     */
1588    public function getShopifyAPIKey()
1589    {
1590        return $this->shopifyAPIKey;
1591    }
1592
1593    /**
1594     * @param mixed $shopifyAPIKey
1595     */
1596    public function setShopifyAPIKey($shopifyAPIKey)
1597    {
1598        $this->shopifyAPIKey = $shopifyAPIKey;
1599    }
1600
1601    /**
1602     * @return mixed
1603     */
1604    public function getShopifyURL()
1605    {
1606        return $this->shopifyURL;
1607    }
1608
1609    /**
1610     * @param mixed $shopifyURL
1611     */
1612    public function setShopifyURL($shopifyURL)
1613    {
1614        $this->shopifyURL = $shopifyURL;
1615    }
1616
1617    /**
1618     * @return mixed
1619     */
1620    public function getShopifyPassword()
1621    {
1622        return $this->shopifyPassword;
1623    }
1624
1625    /**
1626     * @param mixed $shopifyPassword
1627     */
1628    public function setShopifyPassword($shopifyPassword)
1629    {
1630        $this->shopifyPassword = $shopifyPassword;
1631    }
1632
1633    /**
1634     * @return mixed
1635     */
1636    public function getShopifyLocationID()
1637    {
1638        return $this->shopifyLocationID;
1639    }
1640
1641    /**
1642     * @param mixed $shopifyLocationID
1643     */
1644    public function setShopifyLocationID($shopifyLocationID)
1645    {
1646        $this->shopifyLocationID = $shopifyLocationID;
1647    }
1648
1649    /**
1650     * @return mixed
1651     */
1652    public function getBillingActive()
1653    {
1654        return $this->billingActive;
1655    }
1656
1657    /**
1658     * @param mixed $billingActive
1659     */
1660    public function setBillingActive($billingActive)
1661    {
1662        $this->billingActive = $billingActive;
1663    }
1664
1665    /**
1666     * @return mixed
1667     */
1668    public function getBuyTextSMSType()
1669    {
1670        return $this->buyTextSMSType;
1671    }
1672
1673    /**
1674     * @param mixed $buyTextSMSType
1675     */
1676    public function setBuyTextSMSType($buyTextSMSType)
1677    {
1678        $this->buyTextSMSType = $buyTextSMSType;
1679    }
1680
1681    /**
1682     * @return mixed
1683     */
1684    public function getYellowTime()
1685    {
1686        return $this->yellowTime;
1687    }
1688
1689    /**
1690     * @param mixed $yellowTime
1691     */
1692    public function setYellowTime($yellowTime)
1693    {
1694        $this->yellowTime = $yellowTime;
1695    }
1696
1697    /**
1698     * @return mixed
1699     */
1700    public function getRedTime()
1701    {
1702        return $this->redTime;
1703    }
1704
1705    /**
1706     * @param mixed $redTime
1707     */
1708    public function setRedTime($redTime)
1709    {
1710        $this->redTime = $redTime;
1711    }
1712
1713    /**
1714     * @return mixed
1715     */
1716    public function getFiveStarsStoreID()
1717    {
1718        return $this->fiveStarsStoreID;
1719    }
1720
1721    /**
1722     * @param mixed $fiveStarsStoreID
1723     */
1724    public function setFiveStarsStoreID($fiveStarsStoreID)
1725    {
1726        $this->fiveStarsStoreID = $fiveStarsStoreID;
1727    }
1728
1729    /**
1730     * @return mixed
1731     */
1732    public function getFiveStarsSoftwareID()
1733    {
1734        return $this->fiveStarsSoftwareID;
1735    }
1736
1737    /**
1738     * @param mixed $fiveStarsSoftwareID
1739     */
1740    public function setFiveStarsSoftwareID($fiveStarsSoftwareID)
1741    {
1742        $this->fiveStarsSoftwareID = $fiveStarsSoftwareID;
1743    }
1744
1745    /**
1746     * @return mixed
1747     */
1748    public function getFiveStarsTaxIncluded()
1749    {
1750        return $this->fiveStarsTaxIncluded;
1751    }
1752
1753    /**
1754     * @param mixed $fiveStarsTaxIncluded
1755     */
1756    public function setFiveStarsTaxIncluded($fiveStarsTaxIncluded)
1757    {
1758        $this->fiveStarsTaxIncluded = $fiveStarsTaxIncluded;
1759    }
1760
1761    /**
1762     * @return mixed
1763     */
1764    public function getFiveStarsBuysIncluded()
1765    {
1766        return $this->fiveStarsBuysIncluded;
1767    }
1768
1769    /**
1770     * @param mixed $fiveStarsBuysIncluded
1771     */
1772    public function setFiveStarsBuysIncluded($fiveStarsBuysIncluded)
1773    {
1774        $this->fiveStarsBuysIncluded = $fiveStarsBuysIncluded;
1775    }
1776
1777    /**
1778     * @return mixed
1779     */
1780    public function getFiveStarsPointsRatio()
1781    {
1782        return $this->fiveStarsPointsRatio;
1783    }
1784
1785    /**
1786     * @param mixed $fiveStarsPointsRatio
1787     */
1788    public function setFiveStarsPointsRatio($fiveStarsPointsRatio)
1789    {
1790        $this->fiveStarsPointsRatio = $fiveStarsPointsRatio;
1791    }
1792
1793    /**
1794     * @return mixed
1795     */
1796    public function getEnableQueueSignIn()
1797    {
1798        return $this->enableQueueSignIn;
1799    }
1800
1801    /**
1802     * @param mixed $enableQueueSignIn
1803     */
1804    public function setEnableQueueSignIn($enableQueueSignIn)
1805    {
1806        $this->enableQueueSignIn = $enableQueueSignIn;
1807    }
1808
1809    /**
1810     * @return mixed
1811     */
1812    public function getQbAccessToken()
1813    {
1814        return $this->qbAccessToken;
1815    }
1816
1817    /**
1818     * @param mixed $qbAccessToken
1819     */
1820    public function setQbAccessToken($qbAccessToken)
1821    {
1822        $this->qbAccessToken = $qbAccessToken;
1823    }
1824
1825    /**
1826     * @return mixed
1827     */
1828    public function getQbRefreshToken()
1829    {
1830        return $this->qbRefreshToken;
1831    }
1832
1833    /**
1834     * @param mixed $qbRefreshToken
1835     */
1836    public function setQbRefreshToken($qbRefreshToken)
1837    {
1838        $this->qbRefreshToken = $qbRefreshToken;
1839    }
1840
1841    /**
1842     * @return mixed
1843     */
1844    public function getQbAccessTokenExpiration()
1845    {
1846        return $this->qbAccessTokenExpiration;
1847    }
1848
1849    /**
1850     * @param mixed $qbAccessTokenExpiration
1851     */
1852    public function setQbAccessTokenExpiration($qbAccessTokenExpiration)
1853    {
1854        $this->qbAccessTokenExpiration = $qbAccessTokenExpiration;
1855    }
1856
1857    /**
1858     * @return mixed
1859     */
1860    public function getQbRefreshTokenExpiration()
1861    {
1862        return $this->qbRefreshTokenExpiration;
1863    }
1864
1865    /**
1866     * @param mixed $qbRefreshTokenExpiration
1867     */
1868    public function setQbRefreshTokenExpiration($qbRefreshTokenExpiration)
1869    {
1870        $this->qbRefreshTokenExpiration = $qbRefreshTokenExpiration;
1871    }
1872
1873    /**
1874     * @return mixed
1875     */
1876    public function getDigitalSignType()
1877    {
1878        return $this->digitalSignType;
1879    }
1880
1881    /**
1882     * @param mixed $digitalSignType
1883     */
1884    public function setDigitalSignType($digitalSignType)
1885    {
1886        $this->digitalSignType = $digitalSignType;
1887    }
1888
1889    /**
1890     * @return mixed
1891     */
1892    public function getQbRealmID()
1893    {
1894        return $this->qbRealmID;
1895    }
1896
1897    /**
1898     * @param mixed $qbRealmID
1899     */
1900    public function setQbRealmID($qbRealmID)
1901    {
1902        $this->qbRealmID = $qbRealmID;
1903    }
1904
1905    /**
1906     * @return int
1907     */
1908    public function getQbEnabled()
1909    {
1910        return $this->qbEnabled;
1911    }
1912
1913    /**
1914     * @param int $qbEnabled
1915     */
1916    public function setQbEnabled($qbEnabled)
1917    {
1918        $this->qbEnabled = $qbEnabled;
1919    }
1920
1921    /**
1922     * @return string|null
1923     */
1924    public function getQbLastSync()
1925    {
1926        return $this->qbLastSync;
1927    }
1928
1929    /**
1930     * @param string|null $qbLastSync
1931     */
1932    public function setQbLastSync($qbLastSync)
1933    {
1934        $this->qbLastSync = $qbLastSync;
1935    }
1936
1937    /**
1938     * Check if QuickBooks integration is configured and enabled
1939     * @return bool
1940     */
1941    public function isQbConfigured()
1942    {
1943        return $this->qbEnabled &&
1944               !empty($this->qbAccessToken) &&
1945               !empty($this->qbRefreshToken) &&
1946               !empty($this->qbRealmID);
1947    }
1948
1949    /**
1950     * Update QB enabled status and last sync timestamp
1951     */
1952    public function updateQbStatus()
1953    {
1954        global $db_name;
1955        $db = dbConnectByName($db_name);
1956        $stmt = $db->prepare("UPDATE stores SET qbEnabled = :enabled, qbLastSync = :lastSync WHERE typeNum = :typeNum");
1957        $stmt->bindValue(":enabled", $this->qbEnabled);
1958        $stmt->bindValue(":lastSync", $this->qbLastSync);
1959        $stmt->bindValue(":typeNum", $this->typeNum);
1960        return $stmt->execute();
1961    }
1962
1963    /**
1964     * @return mixed
1965     */
1966    public function getBillingType()
1967    {
1968        return $this->billingType;
1969    }
1970
1971    /**
1972     * @param mixed $billingType
1973     */
1974    public function setBillingType($billingType): void
1975    {
1976        $this->billingType = $billingType;
1977    }
1978
1979    /**
1980     * @return mixed
1981     */
1982    public function getNextBillingDate()
1983    {
1984        return $this->nextBillingDate;
1985    }
1986
1987    /**
1988     * @param mixed $nextBillingDate
1989     */
1990    public function setNextBillingDate($nextBillingDate): void
1991    {
1992        $this->nextBillingDate = $nextBillingDate;
1993    }
1994
1995    /**
1996     * @return mixed
1997     */
1998    public function getBillingRate()
1999    {
2000        return $this->billingRate;
2001    }
2002
2003    /**
2004     * @param mixed $billingRate
2005     */
2006    public function setBillingRate($billingRate): void
2007    {
2008        $this->billingRate = $billingRate;
2009    }
2010
2011    /**
2012     * @return mixed
2013     */
2014    public function getBillingDiscount()
2015    {
2016        return $this->billingDiscount;
2017    }
2018
2019    /**
2020     * @param mixed $billingDiscount
2021     */
2022    public function setBillingDiscount($billingDiscount): void
2023    {
2024        $this->billingDiscount = $billingDiscount;
2025    }
2026
2027    /**
2028     * @return mixed
2029     */
2030    public function getBillingDiscountDate()
2031    {
2032        return $this->billingDiscountDate;
2033    }
2034
2035    /**
2036     * @param mixed $billingDiscountDate
2037     */
2038    public function setBillingDiscountDate($billingDiscountDate): void
2039    {
2040        $this->billingDiscountDate = $billingDiscountDate;
2041    }
2042
2043    /**
2044     * Get the employee data source for this store
2045     *
2046     * @return string The employee source: 'homegrown', 'wheniwork', or 'homebase'
2047     */
2048    public function getEmployeeSource()
2049    {
2050        // Determine employee source from integration flags
2051        if ($this->homebaseEnable) {
2052            return 'homebase';
2053        }
2054        if ($this->wiwEnable) {
2055            return 'wheniwork';
2056        }
2057
2058        return 'homegrown';
2059    }
2060
2061    /**
2062     * @return string|null
2063     */
2064    public function getHomebaseApiKey()
2065    {
2066        return $this->homebaseApiKey;
2067    }
2068
2069    /**
2070     * @param string|null $homebaseApiKey
2071     */
2072    public function setHomebaseApiKey($homebaseApiKey)
2073    {
2074        $this->homebaseApiKey = $homebaseApiKey;
2075    }
2076
2077    /**
2078     * @return string|null
2079     */
2080    public function getHomebaseLocationId()
2081    {
2082        return $this->homebaseLocationId;
2083    }
2084
2085    /**
2086     * @param string|null $homebaseLocationId
2087     */
2088    public function setHomebaseLocationId($homebaseLocationId)
2089    {
2090        $this->homebaseLocationId = $homebaseLocationId;
2091    }
2092
2093    /**
2094     * @return int
2095     */
2096    public function getHomebaseEnable()
2097    {
2098        return $this->homebaseEnable;
2099    }
2100
2101    /**
2102     * @param int $homebaseEnable
2103     */
2104    public function setHomebaseEnable($homebaseEnable)
2105    {
2106        $this->homebaseEnable = $homebaseEnable;
2107    }
2108
2109    /**
2110     * Get the scheduling provider for this store
2111     *
2112     * @return string The scheduling provider: 'none', 'buyerkiosk', 'wheniwork', or 'homebase'
2113     */
2114    public function getSchedulingProvider(): string
2115    {
2116        return $this->schedulingProvider ?? 'none';
2117    }
2118
2119    /**
2120     * Set the scheduling provider for this store
2121     *
2122     * @param string $schedulingProvider
2123     */
2124    public function setSchedulingProvider(string $schedulingProvider): void
2125    {
2126        $this->schedulingProvider = $schedulingProvider;
2127    }
2128
2129    // Store Hours Configuration (Spec 018)
2130
2131    /**
2132     * Get the default store opening time
2133     *
2134     * @return string Time in HH:MM format (24-hour)
2135     */
2136    public function getDefaultOpenTime(): string
2137    {
2138        return $this->defaultOpenTime ?? '09:00';
2139    }
2140
2141    /**
2142     * Set the default store opening time
2143     *
2144     * @param string $defaultOpenTime Time in HH:MM format (24-hour)
2145     */
2146    public function setDefaultOpenTime(string $defaultOpenTime): void
2147    {
2148        $this->defaultOpenTime = $defaultOpenTime;
2149    }
2150
2151    /**
2152     * Get the default store closing time
2153     *
2154     * @return string Time in HH:MM format (24-hour)
2155     */
2156    public function getDefaultCloseTime(): string
2157    {
2158        return $this->defaultCloseTime ?? '21:00';
2159    }
2160
2161    /**
2162     * Set the default store closing time
2163     *
2164     * @param string $defaultCloseTime Time in HH:MM format (24-hour)
2165     */
2166    public function setDefaultCloseTime(string $defaultCloseTime): void
2167    {
2168        $this->defaultCloseTime = $defaultCloseTime;
2169    }
2170
2171    /**
2172     * Get the timestamp when store hours were last updated
2173     *
2174     * Returns null if hours have never been explicitly configured,
2175     * which is used as the indicator for localStorage migration prompts.
2176     *
2177     * @return string|null Timestamp string or null if never configured
2178     */
2179    public function getHoursLastUpdated(): ?string
2180    {
2181        return $this->hoursLastUpdated;
2182    }
2183
2184    /**
2185     * Set the timestamp when store hours were last updated
2186     *
2187     * @param string|null $hoursLastUpdated Timestamp string or null
2188     */
2189    public function setHoursLastUpdated(?string $hoursLastUpdated): void
2190    {
2191        $this->hoursLastUpdated = $hoursLastUpdated;
2192    }
2193
2194    /**
2195     * Get the ID of the user who last updated store hours
2196     *
2197     * @return int|null User ID or null if never configured
2198     */
2199    public function getHoursUpdatedByUserId(): ?int
2200    {
2201        return $this->hoursUpdatedByUserId;
2202    }
2203
2204    /**
2205     * Set the ID of the user who last updated store hours
2206     *
2207     * @param int|null $hoursUpdatedByUserId User ID or null
2208     */
2209    public function setHoursUpdatedByUserId(?int $hoursUpdatedByUserId): void
2210    {
2211        $this->hoursUpdatedByUserId = $hoursUpdatedByUserId;
2212    }
2213
2214    /**
2215     * Get a feature flag value for this store
2216     *
2217     * Feature flags allow gradual rollout of new features. Flags are stored
2218     * in the `featureFlags` JSON column in the stores table.
2219     *
2220     * @param string $flagName The name of the feature flag to check
2221     * @param mixed $default Default value if flag is not set (default: false)
2222     * @return mixed The flag value or default if not set
2223     */
2224    public function getFeatureFlag($flagName, $default = false)
2225    {
2226        // For now, we'll check environment variables for flags
2227        // This allows enabling flags without database changes during development
2228        $envKey = 'FEATURE_' . strtoupper($flagName);
2229        if (isset($_ENV[$envKey])) {
2230            // Parse environment variable as JSON boolean
2231            $value = $_ENV[$envKey];
2232            if ($value === 'true' || $value === '1') {
2233                return true;
2234            }
2235            if ($value === 'false' || $value === '0') {
2236                return false;
2237            }
2238            return $value;
2239        }
2240
2241        // TODO: In the future, check featureFlags JSON column in database
2242        // Example implementation:
2243        // if (!empty($this->featureFlags)) {
2244        //     $flags = json_decode($this->featureFlags, true);
2245        //     if (isset($flags[$flagName])) {
2246        //         return $flags[$flagName];
2247        //     }
2248        // }
2249
2250        return $default;
2251    }
2252
2253
2254}