RulesRegisterViewController.m 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426
  1. //
  2. // RulesRegisterViewController.m
  3. // kneet
  4. //
  5. // Created by Jason Lee on 3/19/15.
  6. // Copyright (c) 2015 ntels. All rights reserved.
  7. //
  8. @import ObjectiveC.runtime;
  9. #import "JDObject.h"
  10. #import "RequestHandler.h"
  11. #import "RuleModel.h"
  12. #import "DeviceModel.h"
  13. #import "UIImageView+WebCache.h"
  14. #import "CustomTextField.h"
  15. #import "CustomLabel.h"
  16. #import "CustomImageView.h"
  17. #import "CustomButton.h"
  18. #import "CustomAlertView.h"
  19. #import "CustomRadioGroup.h"
  20. #import "CustomTextView.h"
  21. #import "ValidateUtil.h"
  22. #import "PredefinedDeviceViewController.h"
  23. #import "RegisterModeViewController.h"
  24. #import "RulesRegisterViewController.h"
  25. #import "ActionPopTableView.h"
  26. #import "RegisterCmdClsViewController.h"
  27. #import "RegisterPushViewController.h"
  28. #import "RulesViewController.h"
  29. @implementation RulesCreateHeaderTableViewCell
  30. - (void)awakeFromNib {
  31. self.backgroundColor = [UIColor clearColor];
  32. }
  33. @end
  34. @interface RulesCreateTableViewCell () <CustomTextViewDelegate> {
  35. }
  36. @property (weak, nonatomic) ItemModel *item;
  37. @end
  38. @implementation RulesCreateTableViewCell
  39. - (void)awakeFromNib {
  40. self.backgroundColor = [UIColor clearColor];
  41. self.selectionStyle = UITableViewCellSelectionStyleNone;
  42. }
  43. - (void)textViewDidEndEditing:(UITextView *)textView {
  44. ItemSubModel *subItem = _item.pushes[0];
  45. subItem.cmdclsValue = textView.text;
  46. }
  47. - (IBAction)btnDeleteSubItemsTouched:(id)sender {
  48. // if ([_item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  49. // [_item.predDevices removeAllObjects];
  50. // } else if ([_item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  51. // [_item.modes removeAllObjects];
  52. // }
  53. //
  54. // UITableView *tableView = [(RulesRegisterViewController *)[JDFacade facade].currentViewController tableView];
  55. // if (tableView) {
  56. // [tableView reloadRowsAtIndexPaths:@[_indexPath] withRowAnimation:UITableViewRowAnimationNone];
  57. // }
  58. }
  59. @end
  60. @interface RulesCreateTitleTableViewCell () <CustomTextFieldDelegate> {
  61. }
  62. @end
  63. @implementation RulesCreateTitleTableViewCell
  64. - (void)awakeFromNib {
  65. self.selectionStyle = UITableViewCellSelectionStyleNone;
  66. self.backgroundColor = [UIColor clearColor];
  67. _txtRuleTitle.delegate = self;
  68. _txtRuleTitle.keyboardType = UIKeyboardTypeDefault;
  69. _txtRuleTitle.returnKeyType = UIReturnKeyDone;
  70. _txtRuleTitle.placeholder = NSLocalizedString(@"입력", @"입력");
  71. }
  72. - (void)didMoveToSuperview {
  73. _txtRuleTitle.customTextFieldSuperview = CustomTextFieldSuperviewIsViewController;
  74. }
  75. - (void)textFieldDidEndEditing:(UITextField *)textField {
  76. self.txtRuleTitle.hidden = YES;
  77. self.lblRuleTitle.text = [_txtRuleTitle.text isEmptyString] ? _txtRuleTitle.placeholder : _txtRuleTitle.text;
  78. self.lblRuleTitle.hidden = NO;
  79. self.imgvItem.hidden = NO;
  80. //TODO reload tableview?;
  81. }
  82. - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
  83. [super setSelected:selected animated:animated];
  84. if (self.txtRuleTitle.hidden && selected && animated && ![self.txtRuleTitle isFirstResponder]) {
  85. self.lblRuleTitle.hidden = YES;
  86. self.txtRuleTitle.hidden = NO;
  87. self.imgvItem.hidden = YES;
  88. [self.txtRuleTitle becomeFirstResponder];
  89. }
  90. }
  91. @end
  92. @interface RulesRegisterViewController () <UITableViewDelegate, UITableViewDataSource> {
  93. NSString *_ruleId, *_ruleName, *_predRuleId;
  94. NSMutableArray<ItemModel> *_triggers, *_actions, *_conditions;
  95. BOOL _isNotFirstLoading, _isCustomCreation;
  96. NSMutableArray *_arrayForHeader;
  97. UIImage *_iconTrigger, *_iconAction;
  98. ActionPopTableView *_actionPopTableView;
  99. NSArray<DeviceModel> *_geofencingDeviceList;
  100. }
  101. @end
  102. #pragma mark - Class Definition
  103. @implementation RulesRegisterViewController
  104. - (void)viewDidLoad {
  105. [super viewDidLoad];
  106. // Do any additional setup after loading the view.
  107. [self initUI];
  108. [self prepareViewDidLoad];
  109. }
  110. - (void)initUI {
  111. _tableView.dataSource = self;
  112. _tableView.delegate = self;
  113. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  114. _tableView.backgroundColor = [UIColor clearColor];
  115. _tableView.tableFooterView = [[UIView alloc] init]; //this call table events;
  116. _isNotFirstLoading = YES;
  117. _iconTrigger = [UIImage imageNamed:@"tp_01_img_rule_rbox_icon_trigger"];
  118. _iconAction = [UIImage imageNamed:@"tp_01_img_rule_rbox_icon_action"];
  119. //Localization
  120. [_btnComplete setTitle:NSLocalizedString(@"완성", @"완성") forState:UIControlStateNormal];
  121. [_btnCancel setTitle:NSLocalizedString(@"취소", @"취소") forState:UIControlStateNormal];
  122. }
  123. - (void)prepareViewDidLoad {
  124. _isCustomCreation = YES;
  125. if (!_tmpPredRule && !_tmpRuleDetail) {//자유롭게 만들기
  126. _predRuleId = @"0";
  127. } else {
  128. //사전 정의 씬 상세 정보 조회
  129. if (!_tmpRuleDetail) {//사전 정의 씬을 불러온 경우,
  130. _predRuleId = _tmpPredRule.predRuleId;
  131. [self requestPredefinedRuleDetail];
  132. } else {//룰을 수정하는 경우,
  133. _ruleName = _tmpRuleDetail.ruleName;
  134. _predRuleId = _tmpRuleDetail.predRuleId; //FIXME :
  135. [self setRuleDetail];
  136. [self matchRuleDetailWithPredefinedRuleDeatil:_tmpPredRuleDetail];
  137. }
  138. }
  139. }
  140. - (void)viewWillAppear:(BOOL)animated {
  141. [super viewWillAppear:animated];
  142. self.title = !_tmpRuleDetail ? NSLocalizedString(@"홈 규칙 만들기",@"홈 규칙 만들기") : NSLocalizedString(@"홈 규칙 편집", @"홈 규칙 편집");
  143. if (_isNotFirstLoading) {
  144. [_tableView reloadData];
  145. }
  146. }
  147. #pragma mark - Main Logic
  148. - (NSMutableArray<ItemModel> *)triggers {
  149. NSMutableArray<ItemModel> *tmpTriggers = [(NSMutableArray<ItemModel> *)[NSMutableArray alloc] init];
  150. for (ItemModel *trigger in _triggers) {
  151. if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  152. if ((trigger.predDevices)) {
  153. // if ((trigger.predDevices && trigger.predDevices.count)) {
  154. [tmpTriggers addObject:trigger];
  155. break;
  156. }
  157. } else if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  158. if (trigger.modes) {
  159. // if (trigger.modes && trigger.modes.count) {
  160. [tmpTriggers addObject:trigger];
  161. break;
  162. }
  163. } else if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  164. if (trigger.timers) {
  165. // if (trigger.timers && trigger.timers.count) {
  166. [tmpTriggers addObject:trigger];
  167. break;
  168. }
  169. } else if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  170. if (trigger.mobileDevices) {
  171. // if (trigger.mobileDevices && trigger.mobileDevices.count) {
  172. [tmpTriggers addObject:trigger];
  173. break;
  174. }
  175. }
  176. }
  177. return tmpTriggers && tmpTriggers.count ? tmpTriggers : _triggers;
  178. }
  179. //자유 선택 - 커스텀 씬 생성 시 사용
  180. - (void)addItem:(ItemModel *)item {
  181. if (!_isCustomCreation)
  182. return;
  183. if (!_actions) {
  184. _actions = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] init];
  185. }
  186. if ([_actions indexOfObject:item] == NSNotFound) {
  187. [_actions addObject:item];
  188. }
  189. [_tableView reloadData];
  190. }
  191. - (void)requestPredefinedRuleDetail {
  192. NSString *path = [NSString stringWithFormat:API_GET_PRERULE_DETAIL, _predRuleId];
  193. [[RequestHandler handler] sendAsyncGetRequestAPIPath:path parameters:nil modelClass:[PredefinedRuleDetailModel class] completion:^(id responseObject) {
  194. if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
  195. return;
  196. }
  197. PredefinedRuleDetailModel *predefinedRuleDetail = (PredefinedRuleDetailModel *) responseObject;
  198. if (predefinedRuleDetail) {//API 성공 ,
  199. if (!_tmpRuleDetail) {//생성모드일 경우,
  200. [self setPredefinedRuleDetail:predefinedRuleDetail];
  201. }
  202. // else {//수정모드일 경우,
  203. // [self matchRuleDetailWithPredefinedRuleDeatil:predefinedRuleDetail];
  204. // }
  205. }
  206. } failure:^(id errorObject) {
  207. JDErrorModel *error = (JDErrorModel *)errorObject;
  208. [[JDFacade facade] alert:error.errorMessage];
  209. }];
  210. }
  211. //각 아이템별 카운트를 설정함
  212. - (void)setPredefinedRuleDetail:(PredefinedRuleDetailModel *)predefinedRuleDetail {//각 아이템별 카운트를 설정함
  213. _triggers = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:predefinedRuleDetail.triggers];
  214. _actions = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:predefinedRuleDetail.actions];
  215. _conditions = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:predefinedRuleDetail.conditions];
  216. [_tableView reloadData];
  217. }
  218. + (ModeModel *)mode:(NSString *)modeId {
  219. ModeModel *foundedMode = nil;
  220. for (ModeModel *mode in [JDFacade facade].modeList) {
  221. if ([modeId isEqualToString:mode.modeId]) {
  222. foundedMode = mode;
  223. break;
  224. }
  225. }
  226. return foundedMode;
  227. }
  228. + (void)setSubItemsFromItem:(NSArray<ItemModel> *)items {
  229. for (ItemModel *item in items) {//트리거 설정
  230. NSString *subTypeCode = item.itemSubTypeCode;
  231. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  232. item.predDevices = (NSMutableArray<PredefinedDeviceModel> *)[[NSMutableArray alloc] init];
  233. for (ItemSubModel *subItem in item.subItems) {
  234. PredefinedDeviceModel *pdevice = [[PredefinedDeviceModel alloc] initWithSubItem:subItem];
  235. [item.predDevices addObject:pdevice];
  236. }
  237. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  238. item.modes = (NSMutableArray<ModeModel> *)[[NSMutableArray alloc] init];
  239. for (ItemSubModel *subItem in item.subItems) {
  240. ModeModel *mode = [[ModeModel alloc] initWithSubItem:subItem];
  241. [item.modes addObject:mode];
  242. }
  243. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  244. item.pushes = (NSMutableArray<ItemSubModel> *)[[NSMutableArray alloc] initWithArray:item.subItems];
  245. }
  246. }
  247. }
  248. - (void)setRuleDetail {//각 아이템별 카운트를 설정함
  249. _triggers = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] initWithArray:_tmpRuleDetail.triggers copyItems:YES];
  250. _actions = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] initWithArray:_tmpRuleDetail.actions copyItems:YES];
  251. _conditions = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:_tmpRuleDetail.conditions];
  252. for (ItemModel *item in _triggers) {//트리거
  253. NSIndexSet *isDeleted = [item.subItems indexesOfObjectsPassingTest:^BOOL(ItemSubModel *subItem, NSUInteger idx, BOOL *stop) {
  254. return [subItem.deleteYn boolValue];
  255. }];
  256. [item.subItems removeObjectsAtIndexes:isDeleted];
  257. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//집이 변할때 경우,
  258. [item.predDevices removeObjectsAtIndexes:isDeleted];
  259. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  260. [item.modes removeObjectsAtIndexes:isDeleted];
  261. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  262. [item.mobileDevices removeObjectsAtIndexes:isDeleted];
  263. }
  264. }
  265. for (ItemModel *item in _actions) {//액션
  266. NSIndexSet *isDeleted = [item.subItems indexesOfObjectsPassingTest:^BOOL(ItemSubModel *subItem, NSUInteger idx, BOOL *stop) {
  267. return [subItem.deleteYn boolValue];
  268. }];
  269. [item.subItems removeObjectsAtIndexes:isDeleted];
  270. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  271. [item.predDevices removeObjectsAtIndexes:isDeleted];
  272. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  273. [item.modes removeObjectsAtIndexes:isDeleted];
  274. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  275. [item.pushes removeObjectsAtIndexes:isDeleted];
  276. }
  277. }
  278. // [RulesRegisterViewController setSubItemsFromItem:_triggers];
  279. // [RulesRegisterViewController setSubItemsFromItem:_actions];
  280. // [RulesRegisterViewController setSubItemsFromItem:_conditions];
  281. }
  282. //룰 수정 시 - 아이템에 사전정의 아이템의 서브타입 코드를 넣어줌, 사전정의 아이템을 추가함.
  283. + (void)appendItem:(NSMutableArray<ItemModel> *)items withPredefinedRuleItems:(NSArray<ItemModel> *)predItems isRuleMode:(BOOL)isRuleMode {
  284. NSInteger i = 0;
  285. for (ItemModel *predItem in predItems) {
  286. NSInteger indx = [items indexOfObjectPassingTest:^BOOL(ItemModel *obj, NSUInteger idx, BOOL *stop) {
  287. if (isRuleMode) {//규칙 모드일 경우,
  288. return [obj.itemSubTypeCode isEqualToString:predItem.itemSubTypeCode];
  289. } else {//Scene 모드일 경우,
  290. return [obj.predActionSequence isEqualToString:predItem.predActionSequence];
  291. }
  292. }];
  293. if (indx == NSNotFound) {
  294. [items insertObject:predItem atIndex:i];
  295. } else {
  296. ((ItemModel *)items[i]).itemTypeCode = predItem.itemTypeCode;
  297. }
  298. i++;
  299. }
  300. }
  301. - (void)matchRuleDetailWithPredefinedRuleDeatil:(PredefinedRuleDetailModel *)predRuleDetail {
  302. [RulesRegisterViewController appendItem:_triggers withPredefinedRuleItems:predRuleDetail.triggers isRuleMode:YES];
  303. [RulesRegisterViewController appendItem:_actions withPredefinedRuleItems:predRuleDetail.actions isRuleMode:YES];
  304. [RulesRegisterViewController appendItem:_conditions withPredefinedRuleItems:predRuleDetail.conditions isRuleMode:YES];
  305. [_tableView reloadData];
  306. }
  307. //서브아이템 배열을 리턴함.
  308. - (NSArray *)subItemsForType:(NSArray *)subItems itemSubType:(NSString *)itemSubTypeCode {
  309. NSMutableArray *rSubItems = [[NSMutableArray alloc] init];
  310. if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  311. for (PredefinedDeviceModel *pdevice in subItems) {
  312. NSDictionary *rSubItem = @{@"source_id": pdevice.deviceId,
  313. @"source_sub_id": pdevice.nodeId,
  314. @"condition_type_code": pdevice.conditionTypeCode ? pdevice.conditionTypeCode : [NSNull null],
  315. @"cmdcls_value": pdevice.cmdclsValue,
  316. @"data_type_code": pdevice.dataTypeCode,
  317. };
  318. [rSubItems addObject:rSubItem];
  319. }
  320. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  321. for (ModeModel *mode in subItems) {
  322. NSDictionary *rSubItem = @{@"source_id": @"VAR",
  323. @"cmdcls_value": mode.modeId};
  324. [rSubItems addObject:rSubItem];
  325. }
  326. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  327. //at once.
  328. for (ItemSubModel *subItem in subItems) {
  329. NSDictionary *rSubItem = @{
  330. @"source_id": subItem.sourceId,
  331. @"cmdcls_value": subItem.cmdclsValue,
  332. @"condition_type_code" : subItem.conditionTypeCode,
  333. @"data_type_code": @"03"};
  334. [rSubItems addObject:rSubItem];
  335. }
  336. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  337. for (ItemSubModel *subItem in subItems) {
  338. NSDictionary *rSubItem = @{@"hour": subItem.hour,
  339. @"minute": subItem.minute};
  340. [rSubItems addObject:rSubItem];
  341. }
  342. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  343. for (DeviceModel *device in subItems) {
  344. NSDictionary *rSubItem = @{@"source_id": device.deviceId,
  345. @"source_sub_id": device.nodeId,
  346. @"condition_type_code": device.conditionTypeCode,
  347. @"cmdcls_value": device.cmdclsValue,
  348. @"data_type_code": device.dataTypeCode,
  349. };
  350. [rSubItems addObject:rSubItem];
  351. }
  352. }
  353. return rSubItems;
  354. }
  355. //아이템 배열을 리턴함.
  356. - (NSArray *)items:(NSArray<ItemModel> *)items {
  357. //triggers, actions, conditions
  358. NSMutableArray *rItems = [[NSMutableArray alloc] init];
  359. for (ItemModel *item in items) {
  360. NSDictionary *dic = nil;
  361. NSMutableArray *subItems = [[NSMutableArray alloc] init];
  362. NSArray *pdevices = [self subItemsForType:item.predDevices itemSubType:ksItemSubTypeCodeDevice];
  363. NSArray *modes = [self subItemsForType:item.modes itemSubType:ksItemSubTypeCodeMode];
  364. NSArray *pushes = [self subItemsForType:item.pushes itemSubType:ksItemSubTypeCodeAppPush];
  365. NSArray *timers = [self subItemsForType:item.timers itemSubType:ksItemSubTypeCodeTimer];
  366. NSArray *geofencings = [self subItemsForType:item.mobileDevices itemSubType:ksItemSubTypeCodeGeoFencing];
  367. if (pdevices && pdevices.count) {//device
  368. [subItems addObjectsFromArray:pdevices];
  369. }
  370. if (modes && modes.count) {//mode
  371. [subItems addObjectsFromArray:modes];
  372. }
  373. if (pushes && pushes.count) {//push
  374. [subItems addObjectsFromArray:pushes];
  375. }
  376. if (timers && timers.count) {//timer
  377. [subItems addObjectsFromArray:timers];
  378. }
  379. if (geofencings && geofencings.count) {//geofence
  380. [subItems addObjectsFromArray:geofencings];
  381. }
  382. if (subItems.count) {
  383. dic = @{@"pred_item_sequence": item.predItemSequence,
  384. @"item_name": item.itemName,
  385. @"item_sub_type_code": item.itemSubTypeCode,
  386. @"item_sub": subItems};
  387. [rItems addObject:dic];
  388. }
  389. }
  390. return rItems;
  391. }
  392. - (NSArray *)conditions:(NSArray<ItemModel> *)items {//trigger만 해당됨.
  393. //conditions
  394. NSMutableArray *rConditions = [[NSMutableArray alloc] init];
  395. for (ItemModel *item in items) {
  396. ItemSubModel *subItem = nil;
  397. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  398. subItem = item.predDevices && item.predDevices.count ? item.predDevices[0] : nil;
  399. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  400. subItem = item.modes[0];
  401. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  402. subItem = item.timers[0];
  403. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  404. subItem = item.mobileDevices && item.mobileDevices.count ? item.mobileDevices[0] : nil;
  405. }
  406. for (ItemModel *condition in subItem.conditions) {//컨디션 여부
  407. ItemModel *copyCondition = [condition copy];
  408. for (ItemSubModel *subCondition in copyCondition.subItems) {
  409. subCondition.cmdclsValueMsg = nil;
  410. subCondition.dueDate = nil;
  411. subCondition.daysOfWeek = nil;
  412. subCondition.dueTime = nil;
  413. subCondition.homeModes = nil;
  414. subCondition.externHeat = nil;
  415. }
  416. [rConditions addObject:[copyCondition toDictionary]];
  417. }
  418. }
  419. return rConditions;
  420. }
  421. - (void)requestRegisterRule {
  422. NSArray *triggers = [self items:[self triggers]];
  423. NSArray *actions = [self items:_actions];
  424. NSArray *conditions = [self conditions:[self triggers]];
  425. //validate
  426. if (!triggers || !triggers.count) {
  427. [[JDFacade facade] alert:NSLocalizedString(@"선택된 트리거가 없습니다", @"선택된 트리거가 없습니다")];
  428. return;
  429. }
  430. if (!actions || !actions.count) {
  431. [[JDFacade facade] alert:NSLocalizedString(@"액션이 없습니다", @"액션이 없습니다")];
  432. return;
  433. }
  434. //1.트리거 == 모드 && 액션 == 모드
  435. for (ItemModel *trigger in [self triggers]) {
  436. if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  437. for (ItemModel *action in _actions) {
  438. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  439. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다", @"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다")];
  440. return;
  441. }
  442. }
  443. }
  444. }
  445. for (ItemModel *action in _actions) {
  446. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  447. for (NSDictionary *condition in conditions) {//컨디션에 모드가 있을 경우,
  448. if ([condition[@"item_sub_type_code"] isEqualToString:ksItemSubTypeCodeMode]) {
  449. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다", @"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다")];
  450. return;
  451. }
  452. }
  453. }
  454. }
  455. //parameters
  456. NSDictionary *parameter = @{@"pred_rule_id" : _predRuleId,
  457. @"rule_name" : _ruleName,
  458. @"use_yn" : ksYES,
  459. @"triggers": triggers ? triggers : [NSNull null],
  460. @"actions": actions ? actions : [NSNull null],
  461. @"conditions": conditions ? conditions : [NSNull null]};
  462. NSString *path = [NSString stringWithFormat:API_POST_RULE];
  463. [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[JDJSONModel class] completion:^(id responseObject) {
  464. if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
  465. return;
  466. }
  467. JDJSONModel *result = (JDJSONModel *) responseObject;
  468. if (result) {//API 성공 ,
  469. [[JDFacade facade] toast:NSLocalizedString(@"등록되었습니다", @"등록되었습니다")];
  470. [[JDFacade facade] gotoWishMenu:KNMenuIdRules];
  471. }
  472. } failure:^(id errorObject) {
  473. JDErrorModel *error = (JDErrorModel *)errorObject;
  474. [[JDFacade facade] alert:error.errorMessage];
  475. }];
  476. }
  477. - (void)requestModifyRule {
  478. NSArray *triggers = [self items:[self triggers]];
  479. NSArray *actions = [self items:_actions];
  480. NSArray *conditions = [self conditions:[self triggers]];
  481. //validate
  482. // if (!triggers || !triggers.count || !triggers[@"item_sub"] || ![((NSArray *)triggers[@"item_sub"]) count]) {
  483. if (!triggers || !triggers.count) {
  484. [[JDFacade facade] alert:NSLocalizedString(@"트리거가 없습니다", @"트리거가 없습니다")];
  485. return;
  486. }
  487. if (!actions || !actions.count) {
  488. [[JDFacade facade] alert:NSLocalizedString(@"액션이 없습니다", @"액션이 없습니다")];
  489. return;
  490. }
  491. //1.트리거 == 모드 && 액션 == 모드
  492. for (ItemModel *trigger in [self triggers]) {
  493. if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  494. for (ItemModel *action in _actions) {
  495. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  496. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다", @"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다")];
  497. return;
  498. }
  499. }
  500. }
  501. }
  502. for (ItemModel *action in _actions) {
  503. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  504. for (NSDictionary *condition in conditions) {//컨디션에 모드가 있을 경우,
  505. if ([condition[@"item_sub_type_code"] isEqualToString:ksItemSubTypeCodeMode]) {
  506. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다", @"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다")];
  507. return;
  508. }
  509. }
  510. }
  511. }
  512. //parameters
  513. NSDictionary *parameter = @{@"pred_rule_id" : _predRuleId,
  514. @"rule_name" : _ruleName,
  515. @"use_yn" : ksYES,
  516. @"triggers": triggers ? triggers : [NSNull null],
  517. @"actions": actions ? actions : [NSNull null],
  518. @"conditions": conditions ? conditions : [NSNull null]};
  519. NSString *path = [NSString stringWithFormat:API_POST_RULE_MODIFY, _tmpRuleDetail.homegrpRuleId];
  520. [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[RuleModel class] completion:^(id responseObject) {
  521. if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
  522. return;
  523. }
  524. RuleModel *rule = (RuleModel *) responseObject;
  525. if (rule) {//API 성공 ,
  526. _tmpRuleDetail.ruleId = rule.ruleId;
  527. _tmpRuleDetail.ruleName = _ruleName;
  528. RulesViewController *vc = [[JDFacade facade] viewControllerOnNaviationController:[RulesViewController class]];
  529. [vc prepareViewDidLoad];
  530. [[JDFacade facade] toast:@"수정되었습니다."];
  531. [self.navigationController popViewControllerAnimated:YES];
  532. }
  533. } failure:^(id errorObject) {
  534. JDErrorModel *error = (JDErrorModel *)errorObject;
  535. [[JDFacade facade] alert:error.errorMessage];
  536. }];
  537. }
  538. #pragma mark - UITableView DataSource & Delegate
  539. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  540. return 3;
  541. }
  542. - (NSString *)titleForSectionHeader:(NSInteger)section {
  543. NSString *title = nil;
  544. switch (section) {
  545. case 0:
  546. title = NSLocalizedString(@"언제 실행할까요?", @"언제 실행할까요?");
  547. break;
  548. case 1:
  549. title = NSLocalizedString(@"무엇을 실행할까요?", @"무엇을 실행할까요?");
  550. break;
  551. case 2:
  552. title = NSLocalizedString(@"규칙에 이름을 붙여주세요", @"규칙에 이름을 붙여주세요");
  553. break;
  554. }
  555. return title;
  556. }
  557. - (UIImage *)imageForSection:(NSInteger)section {
  558. UIImage *image = nil;
  559. switch (section) {
  560. case 0:
  561. image = _iconTrigger;
  562. break;
  563. case 1:
  564. image = _iconAction;
  565. break;
  566. case 2:
  567. break;
  568. }
  569. return image;
  570. }
  571. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  572. UIView *view = _arrayForHeader.count > section ? _arrayForHeader[section] : nil;
  573. if (!view) {
  574. RulesCreateHeaderTableViewCell *hcell = (RulesCreateHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"HeaderCellIdentifier"];
  575. CGFloat height = [self tableView:tableView heightForHeaderInSection:section];
  576. hcell.frame = CGRectMake(0, 0, IPHONE_WIDTH, height);
  577. if (section == 0) {
  578. hcell.imgvTop.hidden = YES;
  579. hcell.constraintHeaderTitleTop.constant = 10;
  580. }
  581. view = [[UIView alloc] initWithFrame:hcell.frame];
  582. [view addSubview:hcell];
  583. hcell.lblHeaderTitle.text = [self titleForSectionHeader:section];
  584. [_arrayForHeader insertObject:view atIndex:section];
  585. }
  586. return view;
  587. }
  588. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  589. if (section == 0) {
  590. return 65.0f;
  591. }
  592. return 72.0f;
  593. }
  594. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  595. return 0.01f;
  596. }
  597. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  598. NSInteger count = 0;
  599. if (section == 2) {
  600. count = 1;
  601. } else if (section == 0) {
  602. count = [self triggers].count;
  603. } else if (section == 1) {
  604. count = _actions.count + _isCustomCreation;
  605. }
  606. // else if (section == 2) {
  607. // count = _conditions.count;
  608. // }
  609. return count;
  610. }
  611. + (CGFloat)heightForSubItems:(ItemModel *)item isTrigger:(BOOL)isTrigger {
  612. NSString *subTypeCode = item.itemSubTypeCode;
  613. CGFloat width = IPHONE_WIDTH - 80;
  614. CustomLabel *lblTemp = [[CustomLabel alloc] initWithFrame:CGRectMake(0, 0, width, 20)];
  615. lblTemp.font = [UIFont systemFontOfSize:kUIFontSize06];
  616. lblTemp.numberOfLines = 0;
  617. CGFloat titleHeight = 0.0f;
  618. if (isTrigger) {//triggers
  619. CGFloat twidth = IPHONE_WIDTH - 80 - 25;
  620. CustomLabel *lblTitle = [[CustomLabel alloc] initWithFrame:CGRectMake(0, 0, twidth, 55)];
  621. lblTitle.font = [UIFont systemFontOfSize:kUIFontSize01];
  622. lblTitle.numberOfLines = 0;
  623. //타이틀 사이즈를 구함.
  624. ItemSubModel *subItem = [RulesRegisterViewController subItemAndfillTriggerTitle:lblTitle item:item];
  625. if (subItem) {//삭제 버튼이 있을 경우,
  626. twidth = IPHONE_WIDTH - 80 - 25 - 30;
  627. }
  628. titleHeight = [CommonUtil getSizeFromString:lblTitle.text font:lblTitle.font width:twidth].height;
  629. titleHeight = titleHeight < 55.0f ? 0.0f : titleHeight - 55.0f; //원래 차지하는 사이즈만큼 빼줌.
  630. for (ItemModel *condition in subItem.conditions) {
  631. //TODO : 컨디션은 1개의 서브 컨디션을 갖음 (0.6 버전)
  632. ItemSubModel *subCondition = condition.subItems[0];
  633. [self fillConditionSubItemToLabel:lblTemp item:subCondition itemSubTypeCode:condition.itemSubTypeCode];
  634. }
  635. } else {//actions
  636. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  637. [RulesRegisterViewController fillPredDeviceSubItemsToLabel:lblTemp item:item];
  638. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  639. [RulesRegisterViewController fillModeSubItemsToLabel:lblTemp item:item];
  640. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  641. CGFloat twidth = IPHONE_WIDTH - 80 - 25;
  642. CustomLabel *lblTitle = [[CustomLabel alloc] initWithFrame:CGRectMake(0, 0, twidth, 55)];
  643. lblTitle.font = [UIFont systemFontOfSize:kUIFontSize01];
  644. lblTitle.numberOfLines = 0;
  645. //타이틀 사이즈를 구함.
  646. if (item.pushes && item.pushes.count) {//삭제 버튼이 있을 경우,
  647. twidth = IPHONE_WIDTH - 80 - 25 - 30;
  648. }
  649. titleHeight = [CommonUtil getSizeFromString:lblTitle.text font:lblTitle.font width:twidth].height;
  650. titleHeight = titleHeight < 55.0f ? 0.0f : titleHeight - 55.0f; //원래 차지하는 사이즈만큼 빼줌.
  651. [RulesRegisterViewController fillPushesSubItemsToLabel:lblTemp item:item];
  652. }
  653. }
  654. CGFloat height = [CommonUtil getSizeFromAttributeString:lblTemp.attributedText width:width].height;
  655. return height + titleHeight; //add margin
  656. }
  657. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  658. CGFloat height = 0;
  659. if (indexPath.section == 0 || indexPath.section == 1) {
  660. //calcualate subItemsText
  661. NSArray *items = nil;
  662. if (indexPath.section == 0) {
  663. items = [self triggers];
  664. } else if (indexPath.section == 1) {
  665. items = _actions;
  666. if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가)
  667. height = 60.0f;
  668. return height;
  669. }
  670. }
  671. ItemModel *item = items[indexPath.row];
  672. CGFloat adjustHeight = [RulesRegisterViewController heightForSubItems:item isTrigger:indexPath.section == 0];
  673. adjustHeight = adjustHeight > 0 ? adjustHeight + 15 + 20 : adjustHeight;
  674. height = 60 + adjustHeight;
  675. } else if (indexPath.section == 2) {
  676. height = 89.0f;
  677. }
  678. return height;
  679. }
  680. + (void)fillPredDeviceSubItemsToLabel:(CustomLabel *)label item:(ItemModel *)item {
  681. for (PredefinedDeviceModel *pdevice in item.predDevices) {
  682. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  683. NSString *prefix = [item.predDevices.firstObject isEqual:pdevice] ? ksEmptyString: @", ";
  684. NSString *deviceName = [NSString stringWithFormat:@"%@(%@)", pdevice.deviceName, pdevice.nodeName];
  685. NSString *text = [NSString stringWithFormat:@"%@● %@", prefix, deviceName];
  686. NSDictionary *attrColor = @{NSForegroundColorAttributeName : [pdevice.deleteYn boolValue] ? kUITextColor02 : kUITextColor01};
  687. NSMutableAttributedString *attrDeviceName = [[NSMutableAttributedString alloc] initWithString:text];
  688. [attrDeviceName addAttributes:attrColor range:[text rangeOfString:deviceName]];
  689. if ([pdevice.deleteYn boolValue]) {
  690. NSDictionary *attrStrike = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)};
  691. [attrDeviceName addAttributes:attrStrike range:[text rangeOfString:deviceName]];
  692. }
  693. [subText appendAttributedString:attrDeviceName];
  694. label.attributedText = subText;
  695. }
  696. }
  697. + (void)fillModeSubItemsToLabel:(CustomLabel *)label item:(ItemModel *)item {
  698. for (ModeModel *mode in item.modes) {
  699. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  700. NSString *prefix = [item.modes.firstObject isEqual:mode] ? ksEmptyString: @", ";
  701. NSString *modeName = [NSString stringWithFormat:@"%@● %@", prefix, mode.modeName];
  702. [subText appendAttributedString:[[NSAttributedString alloc] initWithString:modeName]];
  703. label.attributedText = subText;
  704. }
  705. }
  706. + (void)fillPushesSubItemsToLabel:(CustomLabel *)label item:(ItemModel *)item {
  707. if (item.pushes && item.pushes.count) {
  708. ItemSubModel *push = item.pushes.firstObject;
  709. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  710. [subText appendAttributedString:[[NSAttributedString alloc] initWithString:push.cmdclsValue]];
  711. label.attributedText = subText;
  712. }
  713. }
  714. + (void)fillConditionSubItemToLabel:(CustomLabel *)label item:(ItemSubModel *)subItem itemSubTypeCode:(NSString *)itemSubTypeCode {
  715. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  716. NSString *prefix = [label.attributedText.string isEmptyString] ? ksEmptyString : @"\n";
  717. NSString *cname = nil;
  718. if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeDueDate]) {//기간
  719. cname = NSLocalizedString(@"기간", @"기간");
  720. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeDaysOfWeek]) {//요일
  721. cname = NSLocalizedString(@"요일", @"요일");
  722. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeDueTime]) {//시간
  723. cname = NSLocalizedString(@"시간", @"시간");
  724. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeHomeMode]) {//홈모드
  725. cname = NSLocalizedString(@"홈모드", @"홈모드");
  726. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeExternHeat]) {//바깥온도
  727. cname = NSLocalizedString(@"지역온도", @"지역온도");
  728. }
  729. NSString *deviceName = [NSString stringWithFormat:@"%@ ➜ %@ : %@", prefix, cname, subItem.cmdclsValueMsg];
  730. [subText appendAttributedString:[[NSAttributedString alloc] initWithString:deviceName]];
  731. label.attributedText = subText;
  732. }
  733. + (ItemSubModel *)subItemAndfillTriggerTitle:(CustomLabel *)label item:(ItemModel *)item {
  734. NSString *subTypeCode = item.itemSubTypeCode;
  735. ItemSubModel *subItem = nil;
  736. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  737. PredefinedDeviceModel *pdevice = item.predDevices && item.predDevices.count ? item.predDevices[0] : nil;
  738. if (pdevice) {
  739. NSDictionary *attrColor = @{NSForegroundColorAttributeName : [pdevice.deleteYn boolValue] ? kUITextColor02 : kUITextColor01};
  740. NSString *condition = [pdevice.conditionTypeCode isEqualToString:@"02"] ? NSLocalizedString(@"미만 시", @"미만 시") : ksEmptyString;
  741. condition = [pdevice.conditionTypeCode isEqualToString:@"04"] ? NSLocalizedString(@"초과 시", @"초과 시") : condition;
  742. NSString *deviceName = [NSString stringWithFormat:@"\n%@ : %@ %@ %@", pdevice.deviceName, pdevice.nodeName, pdevice.cmdclsValue, condition];
  743. NSMutableAttributedString *attrDeviceName = [[NSMutableAttributedString alloc] initWithString:deviceName];
  744. [attrDeviceName addAttributes:attrColor range:[deviceName rangeOfString:deviceName]];
  745. if ([pdevice.deleteYn boolValue]) {
  746. NSDictionary *attrStrike = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)};
  747. [attrDeviceName addAttributes:attrStrike range:[deviceName rangeOfString:deviceName]];
  748. }
  749. NSMutableAttributedString *titleText = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@", item.itemName]];
  750. [titleText appendAttributedString:attrDeviceName];
  751. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  752. [titleText setAttributes:titleColor range:[item.itemName rangeOfString:item.itemName]];
  753. label.attributedText = titleText;
  754. subItem = pdevice;
  755. }
  756. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//홈모드일 경우,
  757. ModeModel *mode = item.modes && item.modes.count ? item.modes[0] : nil;
  758. if (mode) {
  759. NSString *modeTitle = [NSString stringWithFormat:NSLocalizedString(@"[%@]로 바뀔 때", @"[%@]로 바뀔 때"), mode.modeName];
  760. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  761. label.attributedText = [[NSMutableAttributedString alloc] initWithString:modeTitle attributes:titleColor];
  762. subItem = mode;
  763. }
  764. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  765. subItem = item.timers && item.timers.count ? item.timers[0] : nil;
  766. if (subItem) {
  767. NSInteger phour = [subItem.hour integerValue];
  768. NSString *period = phour < 12 ? NSLocalizedString(@"오전", @"오전") : NSLocalizedString(@"오후", @"오후");
  769. if ([period isEqualToString:NSLocalizedString(@"오후", @"오후")]) {
  770. phour -= 12;
  771. }
  772. NSString *title = [NSString stringWithFormat:NSLocalizedString(@"%@ %zd시 %@분", @"%@ %zd시 %@분"), period, phour, subItem.minute];
  773. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  774. label.attributedText = [[NSMutableAttributedString alloc] initWithString:title attributes:titleColor];
  775. }
  776. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  777. if (item.mobileDevices && item.mobileDevices.count) {
  778. NSString *geoMode = nil;
  779. NSMutableString *fam = [[NSMutableString alloc] init];
  780. for (DeviceModel *device in item.mobileDevices) {
  781. if (!geoMode) {
  782. subItem = device;
  783. geoMode = [device.cmdclsValue isEqualToString:@"TRUE"] ? NSLocalizedString(@"도착할 때", @"도착할 때") : NSLocalizedString(@"출발할 때", @"출발할 때");
  784. }
  785. NSString *prefix = [fam isEmptyString] ? @"" : @", ";
  786. [fam appendFormat:@"%@%@ (%@)", prefix, device.nickname, device.deviceName];
  787. }
  788. NSString *title = [NSString stringWithFormat:@"%@\n%@", geoMode, fam];
  789. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  790. NSMutableAttributedString *attrTitle = [[NSMutableAttributedString alloc] initWithString:title];
  791. [attrTitle setAttributes:titleColor range:[title rangeOfString:geoMode]];
  792. label.attributedText = attrTitle;
  793. }
  794. }
  795. return subItem;
  796. }
  797. + (void)fillCell:(RulesCreateTableViewCell *)cell item:(ItemModel *)item isTrigger:(BOOL)isTrigger {
  798. cell.lblItemName.attributedText = [[NSAttributedString alloc] initWithString:item.itemName];
  799. cell.lblSubItems.text = ksEmptyString;
  800. cell.lblSubItems.hidden = YES;
  801. NSString *subTypeCode = item.itemSubTypeCode;
  802. CGFloat titleHeight = 0.0f;
  803. CGFloat adjustHeight = 0.0f;
  804. cell.item = item;
  805. ItemSubModel *subItem = nil;
  806. if (isTrigger) {//triggers
  807. subItem = [RulesRegisterViewController subItemAndfillTriggerTitle:cell.lblItemName item:item];
  808. cell.lblSubItems.hidden = !(subItem.conditions && subItem.conditions.count);
  809. CGFloat deleteWidth = !subItem ? 0 : 30.0f;
  810. cell.constraintTitleLabelRight.constant = !subItem ? -20.0f : -50.0f;
  811. titleHeight = [CommonUtil getSizeFromAttributeString:cell.lblItemName.attributedText width:IPHONE_WIDTH - 80 - 25.0f - deleteWidth].height; //padding, image margin
  812. titleHeight = titleHeight <= 55.0f ? 0.0f : titleHeight - 55.0f;
  813. cell.btnDeleteSubItems.hidden = !subItem; //트리거가 있는 경우,
  814. //컨디션이 있을 경우,
  815. cell.lineview.hidden = cell.lblSubItems.hidden;
  816. if (!cell.lblSubItems.hidden) {//컨디션이 있을 경우,
  817. for (ItemModel *condition in subItem.conditions) {
  818. //TODO : 컨디션은 1개의 서브 컨디션을 갖음 (0.6 버전)
  819. ItemSubModel *subCondition = condition.subItems[0];
  820. [self fillConditionSubItemToLabel:cell.lblSubItems item:subCondition itemSubTypeCode:condition.itemSubTypeCode];
  821. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height;
  822. }
  823. }
  824. } else {//actions
  825. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  826. cell.lblSubItems.hidden = !item.predDevices.count;
  827. cell.lineview.hidden = cell.btnDeleteSubItems.hidden = cell.lblSubItems.hidden;
  828. [self fillPredDeviceSubItemsToLabel:cell.lblSubItems item:item];
  829. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height; //subtract left, right margin
  830. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  831. cell.lblSubItems.hidden = !item.modes.count;
  832. cell.lineview.hidden = cell.btnDeleteSubItems.hidden = cell.lblSubItems.hidden;
  833. [self fillModeSubItemsToLabel:cell.lblSubItems item:item];
  834. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height;
  835. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  836. cell.lblSubItems.hidden = !item.pushes.count;
  837. cell.lineview.hidden = cell.btnDeleteSubItems.hidden = cell.lblSubItems.hidden;
  838. //멤버 표시
  839. NSMutableAttributedString *pmem = [[NSMutableAttributedString alloc] init];
  840. for (ItemSubModel *subItem in item.pushes) {
  841. NSString *prefix = [pmem.string isEmptyString] ? @"\n" : @", ";
  842. NSDictionary *attrColor = @{NSForegroundColorAttributeName : [subItem.deleteYn boolValue] ? kUITextColor02 : kUITextColor01};
  843. NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@", prefix, subItem.sourceName]];
  844. [attrString addAttributes:attrColor range:[attrString.string rangeOfString:subItem.sourceName]];
  845. if ([subItem.deleteYn boolValue]) {
  846. NSDictionary *attrStrike = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)};
  847. [attrString addAttributes:attrStrike range:[attrString.string rangeOfString:subItem.sourceName]];
  848. }
  849. [pmem appendAttributedString:attrString];
  850. }
  851. NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:item.itemName];
  852. [title appendAttributedString:pmem];
  853. cell.lblItemName.attributedText = title;
  854. //타이틀 높이를 구함.
  855. CGFloat deleteWidth = (!item.pushes || !item.pushes.count) ? 0 : 30.0f;
  856. cell.constraintTitleLabelRight.constant = (!item.pushes || !item.pushes.count) ? -20.0f : -50.0f;
  857. titleHeight = [CommonUtil getSizeFromAttributeString:cell.lblItemName.attributedText width:IPHONE_WIDTH - 80 - 25.0f - deleteWidth].height; //padding, image margin
  858. titleHeight = titleHeight <= 55.0f ? 0.0f : titleHeight - 55.0f;
  859. [self fillPushesSubItemsToLabel:cell.lblSubItems item:item];
  860. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height;
  861. }
  862. if (adjustHeight > 0) {
  863. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  864. NSMutableAttributedString *attrItemName = [[NSMutableAttributedString alloc] initWithAttributedString:cell.lblItemName.attributedText];
  865. [attrItemName addAttributes:titleColor range:[item.itemName rangeOfString:item.itemName]];
  866. cell.lblItemName.attributedText = attrItemName;
  867. }
  868. }
  869. //배경 이미지 설정
  870. UIImage *bgImage = nil;
  871. if ([cell.lblSubItems.text isEmptyString]) {//서브아이템이 없을 경우, static title을 가져옴.
  872. // cell.lblSubItems.text = [ItemModel itemSubTypeString:subTypeCode];
  873. bgImage = subItem ? [UIImage imageNamed:@"tp_01_img_rule_rbox_bg_active"] : [UIImage imageNamed:@"tp_01_img_rule_rbox_bg"];
  874. cell.constraintImgvBgHeight.constant = 55.0f + titleHeight;
  875. } else {
  876. bgImage = [UIImage imageNamed:@"tp_01_img_rule_rbox_bg_active"];
  877. cell.constraintImgvBgHeight.constant = 55.0f + titleHeight + adjustHeight + 15 + 20; //label top, bottom margin add
  878. }
  879. [cell.imgvBg setImage:bgImage];
  880. }
  881. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  882. UITableViewCell *cell = nil;
  883. // NSLog(@"%s\n %zd, %zd", __PRETTY_FUNCTION__, indexPath.section, indexPath.row);
  884. if (indexPath.section == 2) {//타이틀 셀
  885. RulesCreateTitleTableViewCell *tcell = [tableView dequeueReusableCellWithIdentifier:@"TitleCellIdentifier"];
  886. if (tcell == nil) {
  887. tcell = [[RulesCreateTitleTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TitleCellIdentifier"];
  888. }
  889. tcell.txtRuleTitle.text = [tcell.txtRuleTitle.text isEmptyString] ? _ruleName : tcell.txtRuleTitle.text;
  890. tcell.lblRuleTitle.text = [tcell.txtRuleTitle.text isEmptyString] ? NSLocalizedString(@"입력", @"입력") : tcell.txtRuleTitle.text;
  891. cell = tcell;
  892. } else {
  893. RulesCreateTableViewCell *tcell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
  894. if (tcell == nil) {
  895. tcell = [[RulesCreateTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellIdentifier"];
  896. }
  897. NSArray *items = nil;
  898. if (indexPath.section == 0) {
  899. items = [self triggers];
  900. } else if (indexPath.section == 1) {
  901. items = _actions;
  902. UIImage *bgImage = [UIImage imageNamed:@"tp_01_img_rule_rbox_bg"];
  903. tcell.constraintImgvBgHeight.constant = 55.0f;
  904. [tcell.imgvBg setImage:bgImage];
  905. if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가)
  906. tcell.lblItemName.text = NSLocalizedString(@"자유 선택", @"자유 선택");
  907. tcell.lblSubItems.hidden = YES;
  908. tcell.imgvItem.image = [self imageForSection:indexPath.section];
  909. tcell.lineview.hidden = tcell.btnDeleteSubItems.hidden = tcell.lblSubItems.hidden;
  910. return tcell;
  911. }
  912. }
  913. // else if (indexPath.section == 3) {
  914. // items = _conditions;
  915. //
  916. // }
  917. ItemModel *item = items[indexPath.row];
  918. [RulesRegisterViewController fillCell:tcell item:item isTrigger:indexPath.section == 0];
  919. tcell.indexPath = indexPath;
  920. tcell.btnDeleteSubItems.value = item;
  921. if (![tcell.btnDeleteSubItems actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  922. [tcell.btnDeleteSubItems addTarget:self action:@selector(btnDeleteSubItemsTouched:) forControlEvents:UIControlEventTouchUpInside];
  923. }
  924. tcell.imgvItem.image = [self imageForSection:indexPath.section];
  925. cell = tcell;
  926. }
  927. return cell;
  928. }
  929. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  930. if (indexPath.section == 2) { //텍스트필드를 포커스
  931. RulesCreateTitleTableViewCell *cell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:indexPath];
  932. [cell setSelected:YES animated:YES];
  933. return;
  934. } else {
  935. NSIndexPath *ip = [NSIndexPath indexPathForItem:0 inSection:2]; //텍스트필드를 원상태로 되돌림
  936. RulesCreateTitleTableViewCell *cell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:ip];
  937. if (!cell.txtRuleTitle.hidden && [cell.txtRuleTitle isFirstResponder]) {
  938. [cell.txtRuleTitle resignFirstResponder];
  939. }
  940. }
  941. [tableView deselectRowAtIndexPath:indexPath animated:YES];
  942. NSArray *items = nil;
  943. if (indexPath.section == 0) {
  944. items = [self triggers];
  945. } else if (indexPath.section == 1) {
  946. items = _actions;
  947. if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가)
  948. //FIXME : 매번 로드를 해야되는가?
  949. if (!_actionPopTableView) {
  950. _actionPopTableView = [[ActionPopTableView alloc] initFromNib];
  951. _actionPopTableView.isRuleMode = YES;
  952. }
  953. _actionPopTableView.actions = _actions;
  954. [_actionPopTableView.tableView scrollsToTop];
  955. [_actionPopTableView show];
  956. return;
  957. }
  958. }
  959. // else if (indexPath.section == 2) {
  960. // items = _conditions;
  961. // }
  962. ItemModel *item = items[indexPath.row];
  963. UIViewController *vc = nil;
  964. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  965. if (indexPath.section == 0) {//트리거
  966. RegisterCmdClsViewController *cvc = (RegisterCmdClsViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterCmdClsViewController" storyboardName:@"Rules"];
  967. cvc.title = [self titleForSectionHeader:indexPath.section];
  968. cvc.tmpItem = item;
  969. vc = cvc;
  970. } else if (indexPath.section == 1){//액션
  971. PredefinedDeviceViewController *dvc = (PredefinedDeviceViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"PredefinedDeviceViewController" storyboardName:@"Rules"];
  972. dvc.title = [self titleForSectionHeader:indexPath.section];
  973. dvc.predRuleId = _predRuleId;
  974. dvc.tmpItem = item;
  975. vc = dvc;
  976. }
  977. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  978. RegisterModeViewController *mvc = (RegisterModeViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterModeViewController" storyboardName:@"Rules"];
  979. mvc.title = [self titleForSectionHeader:indexPath.section];
  980. mvc.isTrigger = indexPath.section == 0; //0 == trigger
  981. mvc.tmpItem = item;
  982. vc = mvc;
  983. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  984. RegisterPushViewController *tvc = (RegisterPushViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterPushViewController" storyboardName:@"Rules"];
  985. tvc.title = [self titleForSectionHeader:indexPath.section];
  986. tvc.tmpItem = item;
  987. vc = tvc;
  988. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  989. // RegisterTimerViewController *tvc = (RegisterTimerViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterTimerViewController" storyboardName:@"Rules"];
  990. //
  991. // tvc.title = [self titleForSectionHeader:indexPath.section];
  992. // tvc.tmpItem = item;
  993. //
  994. // vc = tvc;
  995. }
  996. [self.navigationController pushViewController:vc animated:YES];
  997. }
  998. - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
  999. // Remove seperator inset
  1000. if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
  1001. [cell setSeparatorInset:UIEdgeInsetsZero];
  1002. }
  1003. // Prevent the cell from inheriting the Table View's margin settings
  1004. if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
  1005. [cell setPreservesSuperviewLayoutMargins:NO];
  1006. }
  1007. // Explictly set your cell's layout margins
  1008. if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
  1009. [cell setLayoutMargins:UIEdgeInsetsZero];
  1010. }
  1011. }
  1012. #pragma mark - UI Events
  1013. - (void)resetAllCheckbox {
  1014. // [_tableView enumarateTableViewCellsUsingBlock:^(UITableViewCell *cell) {
  1015. // ProductTableViewCell *pcell = (ProductTableViewCell *)cell;
  1016. // pcell.chkSelect.checked = NO;
  1017. // }];
  1018. }
  1019. - (void)btnCompleteRuleTouched:(id)sender {
  1020. [self.view endEditing:YES];
  1021. //1.Validate Title
  1022. RulesCreateTitleTableViewCell *tcell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]]; //마지막 섹션
  1023. if (tcell && ![ValidateUtil validateTextfiled:tcell.txtRuleTitle type:ValidateTypeNull title:NSLocalizedString(@"이름", @"이름")]) {
  1024. return;
  1025. }
  1026. if (!_tmpRuleDetail && !tcell) {
  1027. [[JDFacade facade] alert:NSLocalizedString(@"이름을 입력하세요", @"이름을 입력하세요")];
  1028. return;
  1029. }
  1030. _ruleName = !tcell ? _ruleName : tcell.txtRuleTitle.text;
  1031. if (!_tmpRuleDetail) {//생성
  1032. [self requestRegisterRule];
  1033. } else {//수정
  1034. [self requestModifyRule];
  1035. }
  1036. }
  1037. - (IBAction)btnCancelRuleTouched:(id)sender {
  1038. [self.navigationController popViewControllerAnimated:YES];
  1039. }
  1040. - (void)btnDeleteSubItemsTouched:(id)sender {
  1041. CustomButton *btnDeleteSubItems = (CustomButton *)sender;
  1042. ItemModel *item = (ItemModel *)btnDeleteSubItems.value;
  1043. NSInteger section = 0;
  1044. if ([[self triggers] containsObject:item]) {//trigger
  1045. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  1046. item.predDevices = nil;
  1047. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  1048. item.modes = nil;
  1049. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  1050. item.timers = nil;
  1051. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  1052. item.mobileDevices = nil;
  1053. }
  1054. } else if ([_actions containsObject:item]) {//해당 액션을 삭제함.
  1055. ItemModel *action = btnDeleteSubItems.value;
  1056. action.predDevices = nil;
  1057. action.pushes = nil;
  1058. action.modes = nil;
  1059. action.cnt = @"0";
  1060. [_actions removeObject:item];
  1061. section = 1;
  1062. }
  1063. [_tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
  1064. }
  1065. #pragma mark - MemoryWarning
  1066. - (void)didReceiveMemoryWarning {
  1067. [super didReceiveMemoryWarning];
  1068. // Dispose of any resources that can be recreated.
  1069. }
  1070. @end