You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

495 lines
34 KiB

11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
11 months ago
  1. USE [FastMoneyPro_Remit]
  2. GO
  3. /****** Object: StoredProcedure [dbo].[proc_online_customer_login] Script Date: 11/21/2023 10:23:55 PM ******/
  4. SET ANSI_NULLS ON
  5. GO
  6. SET QUOTED_IDENTIFIER ON
  7. GO
  8. ALTER PROC [dbo].[proc_online_customer_login]
  9. @flag VARCHAR(50)
  10. ,@customerEmail VARCHAR(100) = NULL
  11. ,@customerPassword VARCHAR(255) = NULL
  12. ,@country VARCHAR(50) = NULL
  13. ,@ipAddress VARCHAR(100) = NULL
  14. ,@lockReason VARCHAR(500) = NULL
  15. ,@UserInfoDetail VARCHAR(MAX) = NULL
  16. ,@sessionId VARCHAR(60) = NULL
  17. ,@checkCountry VARCHAR(50) = NULL
  18. ,@password VARCHAR(50) = NULL
  19. ,@idType VARCHAR(50) = NULL
  20. ,@idNumber VARCHAR(50) = NULL
  21. ,@LogInfo VARCHAR(MAX) = NULL
  22. AS
  23. -----------------------------------------------------
  24. -- #101 - Mobile Changes , #361 - Multi-Lingual
  25. -----------------------------------------------------
  26. SET NOCOUNT ON;
  27. SET XACT_ABORT ON;
  28. BEGIN TRY
  29. DECLARE
  30. @UserData VARCHAR(200)
  31. ,@lastPwdChangedOn DATETIME
  32. ,@forceChangePwd CHAR(1)
  33. ,@pwdChangeDays VARCHAR(20)
  34. ,@msg VARCHAR(2000)
  35. ,@pwdChangeWarningDays VARCHAR(5)
  36. ,@lastLoginDate DATETIME
  37. DECLARE @email VARCHAR(100)
  38. ,@customerPwd VARCHAR(50)
  39. ,@isActive CHAR(1)
  40. ,@onlineUser CHAR(1)
  41. ,@isLocked VARCHAR(1)
  42. ,@ccountry VARCHAR(50)
  43. ,@customerStatus CHAR(1)
  44. ,@loginAttempt INT
  45. ,@existingCustomer INT
  46. IF @flag = 'check-id'
  47. BEGIN
  48. IF EXISTS(SELECT FULLNAME FROM CUSTOMERMASTER (NOLOCK) WHERE IDNUMBER = @idNumber) OR
  49. EXISTS(SELECT 'x' FROM dbo.CustomerMasterTemp AS CM(NOLOCK) WHERE IDNUMBER = @idNumber AND createdBy IS NOT NULL)
  50. BEGIN
  51. SELECT 1 ERRORCODE,'Already exists!' MSG,NULL
  52. RETURN
  53. END
  54. SELECT 0 ERRORCODE,'Success' MSG,NULL
  55. RETURN
  56. END
  57. IF @flag = 'checkIp'
  58. BEGIN
  59. IF NOT EXISTS( SELECT COUNTRYNAME FROM COUNTRYMASTER WITH (NOLOCK)
  60. WHERE ISNULL(allowOnlineCustomer,'N')='Y' AND upper(COUNTRYNAME)=upper(@checkCountry))
  61. BEGIN
  62. SELECT 1 ERRORCODE,'NOT AVAILABLE' MSG,NULL
  63. RETURN
  64. END
  65. ELSE
  66. BEGIN
  67. SELECT 0 ERRORCODE,'AVAILABLE' MSG,NULL
  68. END
  69. END
  70. IF @flag = 'l'
  71. BEGIN
  72. IF NOT EXISTS(SELECT 'x' FROM customerMaster WITH(NOLOCK) WHERE email=@customerEmail)
  73. BEGIN
  74. SELECT 1 errorCode, 'Login Failed - Invalid username or password!' msg, @customerEmail id
  75. RETURN
  76. END
  77. SELECT @email=email,
  78. @customerPwd=customerPassword,
  79. @isActive=isactive,
  80. @onlineUser=onlineuser,
  81. @isLocked=isLocked,
  82. @ccountry=country,
  83. @customerStatus=customerStatus,
  84. @lastLoginDate=lastLoginTs,
  85. @loginAttempt = ISNULL(invalidAttemptCount, 0),
  86. @existingCustomer= ISNULL(isexistingcustomer,0)
  87. FROM customerMaster WITH (NOLOCK)
  88. WHERE email=@customerEmail --and ISNULL(onlineUser, 'N')='Y'
  89. SET @UserData ='User: '+ @customerEmail +' User Type:Online User'
  90. DECLARE @attemptsCount INT, @InvalidReason VARCHAR(80), @InvalidMsg VARCHAR(100)
  91. SELECT TOP 1 @attemptsCount = loginAttemptCount FROM passwordFormat WITH(NOLOCK)
  92. IF( @existingCustomer=1 and (@customerPwd IS NULL OR @customerPwd=''))
  93. BEGIN
  94. SELECT 3 errorCode, 'Login Failed. Please click forgot Password to set new password.' msg, @customerEmail id, @attemptsCount ac
  95. SET @UserInfoDetail = 'Reason = Login fails, Invalid password.-:::-'+@UserInfoDetail
  96. EXEC proc_applicationLogs
  97. @flag='login',
  98. @logType='Login fails',
  99. @createdBy = @customerEmail,
  100. @Reason='Not online User',
  101. @UserData = @UserData,
  102. @fieldValue = @UserInfoDetail,
  103. @IP = @ipAddress
  104. RETURN
  105. END
  106. IF (ISNULL(@isLocked, 'N') IN ('B', 'Y')) OR ((@loginAttempt - @attemptsCount) = -1)
  107. BEGIN
  108. SET @UserInfoDetail = 'Reason = Too many wrong attempts .-:::-' + @UserInfoDetail
  109. SELECT 1 errorCode, 'Login Failed - Too many wrong attempts, please contact GME Support!' msg, @customerEmail id, @attemptsCount ac
  110. EXEC proc_applicationLogs
  111. @flag='login',
  112. @logType='Login fails',
  113. @createdBy = @customerEmail,
  114. @Reason= 'Reason = Too many wrong attempts.',
  115. @UserData = @UserData,
  116. @fieldValue = @UserInfoDetail,
  117. @IP = @ipAddress
  118. RETURN
  119. END
  120. PRINT @customerPwd
  121. IF (@customerPwd <> dbo.FNAEncryptString(@customerPassword))
  122. BEGIN
  123. SET @UserInfoDetail = 'Reason = Incorrect password .-:::-' + @UserInfoDetail
  124. SET @loginAttempt = @loginAttempt + 1
  125. UPDATE customerMaster SET invalidAttemptCount = @loginAttempt--, isLocked = CASE WHEN @loginAttempt > @attemptsCount THEN 'B' ELSE 'N' END
  126. WHERE email = @customerEmail and ISNULL(onlineUser, 'N')='Y'
  127. SET @InvalidReason = CASE WHEN @loginAttempt > @attemptsCount THEN 'Number of invalid password attempts exceeded!' ELSE 'Invalid Password' END
  128. SET @InvalidMsg = 'Login Failed - you have ' + CAST((@attemptsCount - @loginAttempt) AS VARCHAR) + ' Attempts Left'
  129. SELECT 1 errorCode, @InvalidMsg msg, @customerEmail id, @attemptsCount ac
  130. EXEC proc_applicationLogs
  131. @flag='login',
  132. @logType='Login fails',
  133. @createdBy = @customerEmail,
  134. @Reason= @InvalidReason,
  135. @UserData = @UserData,
  136. @fieldValue = @UserInfoDetail,
  137. @IP = @ipAddress
  138. RETURN
  139. END
  140. IF (ISNULL(@onlineUser, 'N') = 'N')
  141. BEGIN
  142. SELECT 2 errorCode, 'User is not an Online User' msg, @customerEmail id, @attemptsCount ac
  143. SET @UserInfoDetail = 'Reason = Login fails, Invalid password.-:::-'+@UserInfoDetail
  144. EXEC proc_applicationLogs
  145. @flag='login',
  146. @logType='Login fails',
  147. @createdBy = @customerEmail,
  148. @Reason='Not online User',
  149. @UserData = @UserData,
  150. @fieldValue = @UserInfoDetail,
  151. @IP = @ipAddress
  152. RETURN
  153. END
  154. DECLARE @vPenny CHAR(1),@vCustomerId BIGINT
  155. --SELECT @vCustomerId=CM.customerId , @vPenny = CASE WHEN CM.createdDate < '2018-12-19 11:00:00' THEN 'N' WHEN ISNULL(CC.action,'REQ') = 'REQ' THEN 'Y' ELSE 'N' END
  156. --from customerMaster CM (nolock)
  157. --LEFT JOIN TblCustomerBankVerification CC (nolock) ON CM.customerId = CC.customerId
  158. --WHERE CM.email = @customerEmail
  159. --IF @vPenny = 'Y'
  160. --BEGIN
  161. -- SELECT 1000 errorCode, 'User redirect to penny test verification' mes, @vCustomerId id
  162. -- SET @UserInfoDetail = 'Reason = Login fails, User redirect to penny test verification.-:::-'+@UserInfoDetail
  163. -- EXEC proc_applicationLogs
  164. -- @flag='login',
  165. -- @logType='Login fails',
  166. -- @createdBy = @customerEmail,
  167. -- @Reason='Penny test verification',
  168. -- @UserData = @UserData,
  169. -- @fieldValue = @UserInfoDetail,
  170. -- @IP = @ipAddress
  171. -- RETURN
  172. --END
  173. IF (ISNULL(@isActive, 'Y') = 'N')
  174. BEGIN
  175. SELECT 1 errorCode, 'Your account is Inactive. Please, contact GME Support Team.' msg, @customerEmail id
  176. SET @UserInfoDetail = 'Reason = Login fails, Your account is Inactive. Please, contact your administrator.-:::-'+@UserInfoDetail
  177. EXEC proc_applicationLogs
  178. @flag='login',
  179. @logType='Login fails',
  180. @createdBy = @customerEmail,
  181. @Reason='User is not active ',
  182. @UserData = @UserData,
  183. @fieldValue = @UserInfoDetail,
  184. @IP = @ipAddress
  185. RETURN
  186. END
  187. --IF EXISTS (SELECT 'x' FROM customerMaster (NOLOCK) WHERE email=@customerEmail AND approvedBy IS NULL AND approvedDate IS NULL)
  188. --BEGIN
  189. -- SELECT 1 errorCode, 'Login Failed - Customer registration verification pending please visit nearest GME branch to get verified!' msg, @customerEmail id
  190. -- RETURN
  191. --END
  192. UPDATE customerMaster SET
  193. sessionId=@sessionId
  194. ,lastLoginTs = GETDATE()
  195. ,invalidAttemptCount = 0
  196. WHERE email = @customerEmail and ISNULL(onlineUser, 'N')='Y'
  197. DECLARE @mobileNo VARCHAR(16)
  198. SET @mobileNo = REPLACE(@mobileNo,' ','')
  199. SET @mobileNo = REPLACE(@mobileNo,'-','')
  200. SET @mobileNo = REPLACE(@mobileNo,'+','')
  201. SET @mobileNo = LEFT(@mobileNo,16)
  202. DECLARE @clientUseCode VARCHAR(10), @clientId VARCHAR(50), @clientSecret VARCHAR(50), @accessToken VARCHAR(400), @gmeBankCode VARCHAR(3), @gmeAccountNo VARCHAR(20)
  203. SELECT @clientUseCode = DBO.DECRYPTDB(clientUseCode), @clientId = DBO.DECRYPTDB(clientId), @clientSecret = DBO.DECRYPTDB(clientSecret)
  204. , @accessToken = accessToken, @gmeAccountNo = accountNum, @gmeBankCode = bankCodeStd
  205. FROM KFTC_GME_MASTER (NOLOCK)
  206. SELECT
  207. TOP 1
  208. 0 errorCode
  209. ,'Login success.' msg
  210. ,cu.customerId Id
  211. ,username = cu.email
  212. ,fullName = cu.fullName
  213. ,country = cm.countryName
  214. ,agent_branch_code=cu.branchId
  215. ,agentcode=cu.agentId
  216. ,date_format=NULL
  217. ,limitPerTran=0
  218. ,GMT_value=NULL
  219. ,currencyType=NULL
  220. ,extra_rate_bank=NULL
  221. ,cash_ledger_id=NULL
  222. ,@attemptsCount [ac]
  223. ,sessionTimeOutPeriod=NULL
  224. ,lastLoginTs=GETDATE()
  225. ,cm.countryId
  226. ,[address] = cu.city +'-Provience,South Korea'
  227. ,[address2]=cu.[address2]
  228. ,homePhone=cu.homePhone
  229. ,mobile=cu.mobile
  230. ,cm.countryCode
  231. ,utcTime=8
  232. ,mobile= @mobileNo
  233. ,city=cu.city
  234. ,postalCode=cu.postalCode
  235. ,membershipId=membershipId
  236. ,sdv.detailTitle idType
  237. ,cu.idNumber
  238. ,isForcedPwdChange = ISNULL(isForcedPwdChange,0)
  239. ,customerStatus
  240. ,cu.walletAccountNo
  241. ,primaryBankName=CASE WHEN cu.customerType='11048' THEN 'Mutual savings bank(050)' ELSE 'Kwangju Bank (034)' END
  242. ,nativeCountry = cm1.countryName
  243. ,nativeCountryId = cm1.countryId
  244. ,nativeCountryCode = cm1.countryCode
  245. ,occupation = sd.detailTitle
  246. ,idExpiryDate = CASE WHEN cu.idType='8008' THEN '2059-12-12' ELSE FORMAT(cu.idExpiryDate,'MM/dd/yyyy') END
  247. ,birthDate = FORMAT(cu.dob,'MM/dd/yyyy')
  248. ,accessToken = KFTC.accessToken
  249. ,clientUseCode = @clientUseCode
  250. ,clientId = @clientId
  251. ,clientSecret = @clientSecret
  252. ,gmeAccessToken = @accessToken
  253. ,gmeBankCode = @gmeBankCode
  254. ,gmeAccountNum = @gmeAccountNo
  255. ,rewardPoints= DBO.FNA_GET_AVAILABLE_BALANCE_POINTS(cu.customerId)
  256. ,IsEmailVerified = ISNULL(isEmailVerified,0)
  257. ,cu.SelfieDoc
  258. FROM customerMaster cu WITH(NOLOCK)
  259. LEFT JOIN countryMaster cm WITH (NOLOCK) ON cm.countryId=cu.country
  260. LEFT JOIN countryMaster cm1 with(nolock) on cm1.countryId = cu.nativeCountry
  261. left join staticDataValue sdv with (nolock) on sdv.valueId=cu.idType
  262. left join staticDataValue sd with(nolock) on sd.valueId = cu.occupation
  263. LEFT JOIN dbo.vwBankLists vwbank WITH (NOLOCK) ON cu.bankName=vwbank.rowid
  264. LEFT JOIN KFTC_CUSTOMER_MASTER KFTC(NOLOCK) ON KFTC.customerId = CU.customerId
  265. WHERE cu.email= @customerEmail
  266. and ISNULL(cu.onlineUser, 'N')='Y'
  267. EXEC proc_applicationLogs
  268. @flag='login',
  269. @logType='Login',
  270. @createdBy = @customerEmail,
  271. @Reason='Login',
  272. @UserData = @UserData,
  273. @fieldValue = @UserInfoDetail,
  274. @IP = @ipAddress
  275. END
  276. ELSE IF @flag = 'loc'
  277. BEGIN
  278. UPDATE customerMaster SET
  279. isLocked = 'Y'
  280. WHERE email= @customerEmail and ISNULL(onlineUser, 'N')='Y'
  281. INSERT INTO userLockHistory(userName, lockReason, createdBy, createdDate)
  282. SELECT @customerEmail, @lockReason, 'system',GETDATE()
  283. SELECT 0 errorCode, 'Your account has been locked. Please, contact your administrator.' mes, @customerEmail id
  284. END
  285. ELSE IF @flag='availbal'
  286. BEGIN
  287. SELECT ISNULL(availableBalance, 0.00) AS availableBalance FROM dbo.customerMaster(nolock)
  288. WHERE email=@customerEmail
  289. --SELECT 0 errorCode,ISNULL(a.clr_bal_amt, 0.00) AS availableBalance
  290. --FROM dbo.customerMaster c(nolock)
  291. --INNER JOIN FastMoneyPro_account.dbo.ac_master a(nolock) ON A.acct_num = c.walletAccountNo
  292. --WHERE c.email = @customerEmail
  293. END
  294. ELSE IF @flag='checkpin'
  295. BEGIN
  296. DECLARE @TXN_PIN VARCHAR(30)
  297. IF NOT EXISTS(SELECT 'X' FROM customerMaster WITH (NOLOCK)
  298. WHERE username=@customerEmail and ISNULL(onlineUser, 'N')='Y')
  299. BEGIN
  300. SELECT @email=email,
  301. @customerPwd=customerPassword,
  302. @isActive=isactive,
  303. @onlineUser=onlineuser,
  304. @isLocked=isLocked,
  305. @ccountry=country,
  306. @customerStatus=customerStatus,
  307. @lastLoginDate=lastLoginTs,
  308. @loginAttempt = ISNULL(invalidAttemptPinCount, 0),
  309. @TXN_PIN = txnPin
  310. FROM customerMaster WITH (NOLOCK)
  311. WHERE username=@customerEmail and ISNULL(onlineUser, 'N')='Y'
  312. END
  313. ELSE
  314. BEGIN
  315. SELECT @email=email,
  316. @customerPwd=customerPassword,
  317. @isActive=isactive,
  318. @onlineUser=onlineuser,
  319. @isLocked=isLocked,
  320. @ccountry=country,
  321. @customerStatus=customerStatus,
  322. @lastLoginDate=lastLoginTs,
  323. @loginAttempt = ISNULL(invalidAttemptPinCount, 0),
  324. @TXN_PIN = txnPin
  325. FROM customerMaster WITH (NOLOCK)
  326. WHERE username=@customerEmail and ISNULL(onlineUser, 'N')='Y'
  327. END
  328. IF (ISNULL(@password, '') = ISNULL(@TXN_PIN, '-1'))
  329. BEGIN
  330. UPDATE customerMaster SET
  331. invalidAttemptPinCount = 0
  332. WHERE username = @customerEmail and ISNULL(onlineUser, 'N')='Y'
  333. SELECT 0 errorCode, 'Success' msg, @customerEmail id
  334. RETURN;
  335. END
  336. SELECT TOP 1 @attemptsCount = loginAttemptCount FROM passwordFormat WITH(NOLOCK)
  337. IF (ISNULL(@isLocked, 'N') IN ('B', 'Y')) OR ((@loginAttempt - @attemptsCount) = -1)
  338. BEGIN
  339. SELECT 18 errorCode, 'Too many wrong attempts, please contact JME Support!' mes, @customerEmail id
  340. EXEC proc_applicationLogs
  341. @flag='login',
  342. @logType='Send Transaction',
  343. @createdBy = @customerEmail,
  344. @Reason= 'Reason = Too many wrong attempts sending transaaction.'
  345. RETURN
  346. END
  347. IF (ISNULL(@password, '') <> ISNULL(@TXN_PIN, '-1'))
  348. BEGIN
  349. SET @UserInfoDetail = 'Reason = Incorrect PIN .-:::-' + @UserInfoDetail
  350. SET @loginAttempt = @loginAttempt + 1
  351. UPDATE customerMaster SET invalidAttemptPinCount = @loginAttempt, isLocked = CASE WHEN @loginAttempt > @attemptsCount THEN 'B' ELSE 'N' END
  352. WHERE username = @customerEmail and ISNULL(onlineUser, 'N')='Y'
  353. SET @InvalidReason = CASE WHEN @loginAttempt > @attemptsCount THEN 'Number of invalid PIN attempts exceeded!' ELSE 'Invalid PIN' END
  354. SET @InvalidMsg = 'Send txn Failed - Invalid PIN, you have ' + CAST((@attemptsCount - @loginAttempt) AS VARCHAR) + ' Attempts Left'
  355. SELECT 20 errorCode, @InvalidMsg mes, @customerEmail id
  356. EXEC proc_applicationLogs
  357. @flag='login',
  358. @logType='Send Transaction',
  359. @createdBy = @customerEmail,
  360. @Reason= 'Reason = wrong transaction PIN.'
  361. RETURN
  362. END
  363. END
  364. ELSE IF @flag='checkpass'
  365. BEGIN
  366. IF NOT EXISTS(SELECT 'X' FROM customerMaster WITH (NOLOCK)
  367. WHERE username=@customerEmail and ISNULL(onlineUser, 'N')='Y')
  368. BEGIN
  369. SELECT @email=email,
  370. @customerPwd=customerPassword,
  371. @isActive=isactive,
  372. @onlineUser=onlineuser,
  373. @isLocked=isLocked,
  374. @ccountry=country,
  375. @customerStatus=customerStatus,
  376. @lastLoginDate=lastLoginTs,
  377. @loginAttempt = ISNULL(invalidAttemptCount, 0),
  378. @TXN_PIN = txnPin
  379. FROM customerMaster WITH (NOLOCK)
  380. WHERE username=@customerEmail and ISNULL(onlineUser, 'N')='Y'
  381. END
  382. ELSE
  383. BEGIN
  384. SELECT @email=email,
  385. @customerPwd=customerPassword,
  386. @isActive=isactive,
  387. @onlineUser=onlineuser,
  388. @isLocked=isLocked,
  389. @ccountry=country,
  390. @customerStatus=customerStatus,
  391. @lastLoginDate=lastLoginTs,
  392. @loginAttempt = ISNULL(invalidAttemptCount, 0),
  393. @TXN_PIN = txnPin
  394. FROM customerMaster WITH (NOLOCK)
  395. WHERE username=@customerEmail and ISNULL(onlineUser, 'N')='Y'
  396. END
  397. IF (@customerPwd = dbo.FNAEncryptString(@password))
  398. BEGIN
  399. UPDATE customerMaster SET
  400. invalidAttemptCount = 0
  401. WHERE username = @customerEmail and ISNULL(onlineUser, 'N')='Y'
  402. SELECT 0 errorCode, 'Success' msg, @customerEmail id
  403. RETURN;
  404. END
  405. SELECT TOP 1 @attemptsCount = loginAttemptCount FROM passwordFormat WITH(NOLOCK)
  406. IF (ISNULL(@isLocked, 'N') IN ('B', 'Y')) OR ((@loginAttempt - @attemptsCount) = -1)
  407. BEGIN
  408. SELECT 9 errorCode, 'Too many wrong attempts, please contact GME Support!' mes, @customerEmail id
  409. EXEC proc_applicationLogs
  410. @flag='login',
  411. @logType='Send Transaction',
  412. @createdBy = @customerEmail,
  413. @Reason= 'Reason = Too many wrong attempts sending transaaction.'
  414. RETURN
  415. END
  416. IF (@customerPwd <> dbo.FNAEncryptString(@password))
  417. BEGIN
  418. SET @UserInfoDetail = 'Reason = Incorrect password .-:::-' + @UserInfoDetail
  419. SET @loginAttempt = @loginAttempt + 1
  420. UPDATE customerMaster SET invalidAttemptCount = @loginAttempt, isLocked = CASE WHEN @loginAttempt > @attemptsCount THEN 'B' ELSE 'N' END
  421. WHERE email = @customerEmail and ISNULL(onlineUser, 'N')='Y'
  422. SET @InvalidReason = CASE WHEN @loginAttempt > @attemptsCount THEN 'Number of invalid password attempts exceeded!' ELSE 'Invalid Password' END
  423. SET @InvalidMsg = 'Login Failed - Invalid Password, you have ' + CAST((@attemptsCount - @loginAttempt) AS VARCHAR) + ' Attempts Left'
  424. SELECT 1 errorCode, @InvalidMsg mes, @customerEmail id
  425. EXEC proc_applicationLogs
  426. @flag='login',
  427. @logType='Send Transaction',
  428. @createdBy = @customerEmail,
  429. @Reason= 'Reason = wrong transaction password.'
  430. RETURN
  431. END
  432. END
  433. END TRY
  434. BEGIN CATCH
  435. IF @@TRANCOUNT > 0
  436. ROLLBACK TRANSACTION
  437. DECLARE @errorMessage VARCHAR(MAX)
  438. SET @errorMessage = ERROR_MESSAGE()
  439. EXEC proc_errorHandler 1, @errorMessage,NULL
  440. END CATCH