PageRenderTime 106ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/locadora_em_c/location.c

http://ruby-pro.googlecode.com/
C | 676 lines | 559 code | 74 blank | 43 comment | 114 complexity | 00896c72862841a2cea620de6fed4e29 MD5 | raw file
  1. /*
  2. * File: location.c
  3. *
  4. * Created on 5 de Maio de 2010, 16:23
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <regex.h>
  10. #include "strings.h"
  11. #include "item.h"
  12. #include "exceptions.h"
  13. #include "status.h"
  14. #include "location.h"
  15. /*
  16. * Location module
  17. */
  18. int check_by_id_location(char *input) {
  19. int id;
  20. do {
  21. printf("Qual ID? ");
  22. read_string(input);
  23. } while (!validate_id(input));
  24. id = atoi(input);
  25. // Verificar se o ID existe
  26. if (id > 0 && location_index_exist(id)) {
  27. return id;
  28. } else {
  29. printf(ID_NOT_FOUND_ERROR, __FILE__, "locacao");
  30. return NON_EXIST;
  31. }
  32. }
  33. Location * location_malloc() {
  34. Location *location = malloc(sizeof (Location));
  35. if (!location) {
  36. printf(ALLOC_ERROR, __FILE__);
  37. exit(EXIT_FAILURE);
  38. }
  39. location_initialize(location);
  40. return location;
  41. }
  42. void location_initialize(Location * location) {
  43. location->id = NON_EXIST;
  44. location->id_client = NON_EXIST;
  45. location->date = 0;
  46. location->total = 0.0;
  47. }
  48. Location * search_location_by_id(int id) {
  49. FILE *file_stream = NULL;
  50. Location *location;
  51. file_stream = fopen(LOCATIONS_FILEPATH, "rb");
  52. if (!file_stream) {
  53. printf(READ_OPEN_ERROR, __FILE__, LOCATIONS_FILEPATH);
  54. exit(EXIT_FAILURE);
  55. }
  56. location = location_malloc();
  57. fread(location, sizeof (Location), 1, file_stream);
  58. while (!feof(file_stream)) {
  59. if (location->id == id) {
  60. fclose(file_stream);
  61. return location;
  62. }
  63. fread(location, sizeof (Location), 1, file_stream);
  64. }
  65. fclose(file_stream);
  66. location->id = NON_EXIST;
  67. return location;
  68. }
  69. int locations_file_is_empty() {
  70. FILE *file_stream = NULL;
  71. file_stream = fopen(LOCATIONS_FILEPATH, "rb");
  72. if (file_stream) {
  73. fclose(file_stream);
  74. return FALSE;
  75. } else {
  76. return TRUE;
  77. }
  78. }
  79. int location_index_exist(int index) {
  80. Location *location;
  81. location = location_malloc();
  82. location = search_location_by_id(index);
  83. if (location->id == NON_EXIST) {
  84. free(location);
  85. return FALSE;
  86. }
  87. free(location);
  88. return TRUE;
  89. }
  90. int location_first_index_avaliable() {
  91. FILE *file_stream = NULL;
  92. int old_id = NON_EXIST, new_id = NON_EXIST;
  93. file_stream = fopen(LOCATIONS_ID_FILEPATH, "rb+");
  94. if (file_stream) {
  95. fread(&old_id, sizeof (old_id), 1, file_stream);
  96. rewind(file_stream);
  97. new_id = old_id + 1;
  98. fwrite(&new_id, sizeof (new_id), 1, file_stream);
  99. fclose(file_stream);
  100. return old_id;
  101. } else {
  102. printf("Aviso: arquivo \"%s\" foi criado agora.\n", LOCATIONS_ID_FILEPATH);
  103. /* Nсo conseguiu abrir um arquivo existente, entсo, criarр. */
  104. file_stream = fopen(LOCATIONS_ID_FILEPATH, "wb+");
  105. if (file_stream) {
  106. new_id = 2;
  107. fwrite(&new_id, sizeof (new_id), 1, file_stream);
  108. fclose(file_stream);
  109. return 1;
  110. } else {
  111. printf(CREATE_FILE_ERROR, __FILE__, LOCATIONS_ID_FILEPATH);
  112. exit(EXIT_FAILURE);
  113. }
  114. }
  115. }
  116. int insert_location(Location * location) {
  117. FILE *file_stream = NULL;
  118. location->id = location_first_index_avaliable();
  119. file_stream = fopen(LOCATIONS_FILEPATH, "rb+");
  120. if (file_stream) {
  121. fseek(file_stream, 0, SEEK_END);
  122. if (!fwrite(location, sizeof (Location), 1, file_stream)) {
  123. printf(WRITE_FILE_ERROR, __FILE__, LOCATIONS_FILEPATH);
  124. fclose(file_stream);
  125. return FALSE;
  126. }
  127. fclose(file_stream);
  128. } else {
  129. printf("Aviso: arquivo \"%s\" foi criado agora.\n", LOCATIONS_FILEPATH);
  130. /* Nсo conseguiu abrir um arquivo existente, entсo, criarр. */
  131. file_stream = fopen(LOCATIONS_FILEPATH, "wb+");
  132. if (file_stream) {
  133. if (!fwrite(location, sizeof (Location), 1, file_stream)) {
  134. printf(WRITE_FILE_ERROR, __FILE__, LOCATIONS_FILEPATH);
  135. fclose(file_stream);
  136. return FALSE;
  137. }
  138. fclose(file_stream);
  139. } else {
  140. printf(CREATE_FILE_ERROR, __FILE__, LOCATIONS_FILEPATH);
  141. return FALSE;
  142. }
  143. }
  144. return location->id;
  145. }
  146. int update_location(Location *location) {
  147. FILE *file_stream = NULL;
  148. Location *aux;
  149. file_stream = fopen(LOCATIONS_FILEPATH, "rb+");
  150. if (!file_stream) {
  151. printf(FILE_NOT_FOUND_ERROR, __FILE__, LOCATIONS_FILEPATH);
  152. return FALSE;
  153. }
  154. aux = location_malloc();
  155. // Procurar o registro a ser alterado no arquivo
  156. fread(aux, sizeof (Location), 1, file_stream);
  157. while (!feof(file_stream)) {
  158. if (aux->id == location->id) {
  159. fseek(file_stream, -(sizeof (Location)), SEEK_CUR);
  160. if (!fwrite(location, sizeof (Location), 1, file_stream)) {
  161. printf(WRITE_FILE_ERROR, __FILE__, LOCATIONS_FILEPATH);
  162. fclose(file_stream);
  163. free(aux);
  164. return FALSE;
  165. }
  166. fclose(file_stream);
  167. free(aux);
  168. return TRUE;
  169. }
  170. fread(aux, sizeof (Location), 1, file_stream);
  171. }
  172. // Se chegar atж aqui ж porque nсo encontrou nada
  173. fclose(file_stream);
  174. free(aux);
  175. return FALSE;
  176. }
  177. int erase_location(Location *location) {
  178. FILE *file_stream = NULL, *file_stream_tmp = NULL;
  179. Location *aux;
  180. file_stream = fopen(LOCATIONS_FILEPATH, "rb+");
  181. if (!file_stream) {
  182. printf(FILE_NOT_FOUND_ERROR, __FILE__, LOCATIONS_FILEPATH);
  183. return FALSE;
  184. }
  185. file_stream_tmp = fopen(LOCATIONS_TMP_FILEPATH, "wb");
  186. if (!file_stream_tmp) {
  187. printf(FILE_NOT_FOUND_ERROR, __FILE__, LOCATIONS_TMP_FILEPATH);
  188. return FALSE;
  189. }
  190. aux = location_malloc();
  191. fread(aux, sizeof (Location), 1, file_stream);
  192. while (!feof(file_stream)) {
  193. if (aux->id != location->id) {
  194. fwrite(aux, sizeof (Location), 1, file_stream_tmp);
  195. }
  196. fread(aux, sizeof (Location), 1, file_stream);
  197. }
  198. free(aux);
  199. fclose(file_stream);
  200. fclose(file_stream_tmp);
  201. if (remove(LOCATIONS_FILEPATH)) {
  202. return FALSE;
  203. }
  204. if (rename(LOCATIONS_TMP_FILEPATH, LOCATIONS_FILEPATH)) {
  205. return FALSE;
  206. }
  207. // Verificar se o arquivo ficou com 0 bytes
  208. file_stream = fopen(LOCATIONS_FILEPATH, "rb");
  209. if (!file_stream) {
  210. printf(FILE_NOT_FOUND_ERROR, __FILE__, LOCATIONS_FILEPATH);
  211. return FALSE;
  212. }
  213. fseek(file_stream, 0, SEEK_END);
  214. // Se o arquivo tiver 0 bytes, serр removido.
  215. if (!ftell(file_stream)) {
  216. remove(LOCATIONS_FILEPATH);
  217. }
  218. return TRUE;
  219. }
  220. void copy_location(Location * dest, Location * src) {
  221. dest->id = src->id;
  222. dest->id_client = src->id_client;
  223. dest->date = src->date;
  224. dest->total = src->total;
  225. }
  226. int get_size_locations() {
  227. FILE *file_stream = NULL;
  228. file_stream = fopen(LOCATIONS_FILEPATH, "rb");
  229. if (!file_stream) {
  230. printf(FILE_NOT_FOUND_ERROR, __FILE__, LOCATIONS_FILEPATH);
  231. return FALSE;
  232. }
  233. fseek(file_stream, 0, SEEK_END);
  234. return ftell(file_stream) / sizeof (Location);
  235. }
  236. Location * location_file_to_a() {
  237. FILE * file_stream = NULL;
  238. Location *vetor;
  239. int i, size;
  240. /* Antes de tudo, precisamos testar se hр alguma locaусo no arquivo */
  241. if (locations_file_is_empty()) {
  242. printf(EMPTY_ERROR, __FILE__, "locacao");
  243. return FALSE;
  244. }
  245. file_stream = fopen(LOCATIONS_FILEPATH, "rb");
  246. if (!file_stream) {
  247. printf(FILE_NOT_FOUND_ERROR, __FILE__, LOCATIONS_FILEPATH);
  248. return FALSE;
  249. }
  250. size = get_size_locations();
  251. if (!size) {
  252. printf("%s: Nao foi possivel obter a quantidade de locacoes.\n", __FILE__);
  253. return FALSE;
  254. }
  255. vetor = malloc(size * sizeof (Location));
  256. if (!vetor) {
  257. printf(ALLOC_ERROR, __FILE__);
  258. return FALSE;
  259. }
  260. for (i = 0; i < size; i++) {
  261. fread(vetor + i, sizeof (Location), 1, file_stream);
  262. }
  263. fclose(file_stream);
  264. return vetor;
  265. }
  266. void puts_location(Location * location, char show_id) {
  267. Client * client;
  268. double total_price_to_pay = 0.0;
  269. client = search_client_by_id(location->id_client);
  270. if (client->id == NON_EXIST) {
  271. printf(ID_NOT_FOUND_ERROR, __FILE__, "cliente");
  272. free(client);
  273. return;
  274. }
  275. if (show_id) {
  276. printf("ID da locacao: %d\n", location->id);
  277. }
  278. printf("Cliente [%d]: %s\n", client->id, client->name);
  279. puts_items_by_location(location, FALSE);
  280. total_price_to_pay = get_total_to_pay(location);
  281. printf("\nTOTAL: R$ %.2lf\n", location->total);
  282. printf("TOTAL A PAGAR (com taxa de atraso): R$ %.2lf\n", total_price_to_pay);
  283. free(client);
  284. }
  285. void puts_location_short(Location * location) {
  286. Client * client;
  287. client = search_client_by_id(location->id_client);
  288. printf("ID da locacao: %d\n", location->id);
  289. printf("Cliente [%d]: %s\n", client->id, client->name);
  290. printf("Filmes locados: ");
  291. puts_items_by_location_only_titles(location);
  292. printf("\n\n");
  293. free(client);
  294. }
  295. void puts_location_by_id(int id) {
  296. Location *location;
  297. location = location_malloc();
  298. location = search_location_by_id(id);
  299. if (location->id == NON_EXIST) {
  300. printf(ID_NOT_FOUND_ERROR, __FILE__, "locacao");
  301. free(location);
  302. return;
  303. } else {
  304. puts_location(location, TRUE);
  305. }
  306. free(location);
  307. }
  308. void puts_all_locations() {
  309. FILE *file_stream = NULL;
  310. Location *location;
  311. file_stream = fopen(LOCATIONS_FILEPATH, "rb");
  312. if (!file_stream) {
  313. printf(EMPTY_ERROR, __FILE__, "locacao");
  314. return;
  315. }
  316. location = location_malloc();
  317. printf("\n=======\nLISTA DE LOCACOES: \n\n");
  318. fread(location, sizeof (Location), 1, file_stream);
  319. while (!feof(file_stream)) {
  320. puts_location_short(location);
  321. fread(location, sizeof (Location), 1, file_stream);
  322. }
  323. printf("\n=======\n");
  324. fclose(file_stream);
  325. free(location);
  326. }
  327. void puts_all_locations_by_client(Client *client) {
  328. FILE *file_stream = NULL;
  329. Location *location;
  330. file_stream = fopen(LOCATIONS_FILEPATH, "rb");
  331. if (!file_stream) {
  332. printf(EMPTY_ERROR, __FILE__, "locacao");
  333. return;
  334. }
  335. location = location_malloc();
  336. printf("\n=======\nLISTA DE LOCACOES: \n\n");
  337. fread(location, sizeof (Location), 1, file_stream);
  338. while (!feof(file_stream)) {
  339. if (location->id_client == client->id) {
  340. puts_location_short(location);
  341. }
  342. fread(location, sizeof (Location), 1, file_stream);
  343. }
  344. printf("\n=======\n");
  345. fclose(file_stream);
  346. free(location);
  347. }
  348. void form_location_insert(char *input) {
  349. Location *location;
  350. Client *client;
  351. location = location_malloc();
  352. location->id = insert_location(location);
  353. printf("\n=======\nLOCANDO: \n\n");
  354. // Definir cliente
  355. do {
  356. printf("> A qual cliente quer locar? ");
  357. client = form_client_select(input);
  358. } while (client->id == NON_EXIST);
  359. puts_client(client);
  360. // Tem certeza?
  361. if (!be_sure(input)) {
  362. printf("Abortando locacao.\n\n");
  363. erase_location(location);
  364. free(location);
  365. return;
  366. }
  367. location->id_client = client->id;
  368. free(client);
  369. // Definir filmes
  370. if (form_items_insert(location, input) < 1) {
  371. free(location);
  372. erase_location(location);
  373. printf("Voce precisa inserir algum filme a locacao. Abortando locacao.\n\n");
  374. return;
  375. }
  376. // Imprimir resultado geral
  377. printf("\n>>>> SUMARIO DA LOCACAO <<<< \n\n");
  378. puts_location(location, TRUE);
  379. printf("-------------------------------------\n\n");
  380. if (update_location(location)) {
  381. printf("Locacao foi um sucesso.\n");
  382. } else {
  383. printf("Locacao nao foi completada corretamente!\n");
  384. }
  385. printf("\n=======\n");
  386. free(location);
  387. }
  388. void form_location_update(char *input) {
  389. Location *location;
  390. Client *client;
  391. // Antes de tudo, precisamos testar se hр alguma locaусo no arquivo
  392. if (locations_file_is_empty()) {
  393. printf(EMPTY_ERROR, __FILE__, "locacao");
  394. return;
  395. }
  396. printf("\n=======\nALTERANDO LOCACAO: \n\n");
  397. location = form_location_select(input);
  398. if (location->id == NON_EXIST) {
  399. free(location);
  400. return;
  401. }
  402. // Mostra o resultado da pesquisa
  403. puts_location(location, TRUE);
  404. // Tem certeza?
  405. if (!be_sure(input)) {
  406. printf("Abortando alteracao de locacao.\n\n");
  407. free(location);
  408. return;
  409. }
  410. // Modificando cliente
  411. do {
  412. printf("> Deseja modificar cliente? [S]im ou [n]ao? ");
  413. read_string(input);
  414. } while (strcasecmp(input, "S") && strcasecmp(input, "N"));
  415. if (!strcasecmp(input, "S")) {
  416. do {
  417. printf("> Qual cliente? ");
  418. client = form_client_select(input);
  419. } while (client->id == NON_EXIST);
  420. puts_client(client);
  421. // Tem certeza?
  422. if (!be_sure(input)) {
  423. printf("Abortando alteracao de locacao.\n\n");
  424. free(location);
  425. free(client);
  426. return;
  427. }
  428. location->id_client = client->id;
  429. free(client);
  430. }
  431. do {
  432. printf("> Deseja remover filme? [S]im ou [n]ao? ");
  433. read_string(input);
  434. } while (strcasecmp(input, "S") && strcasecmp(input, "N"));
  435. if (!strcasecmp(input, "S")) {
  436. // Listar todos os filmes da locaусo
  437. puts_items_by_location(location, FALSE);
  438. // Selecionar um ou mais ьtens.
  439. form_items_remove(location, input);
  440. // Listar novamente
  441. puts_items_by_location(location, FALSE);
  442. }
  443. do {
  444. printf("> Deseja adicionar filme? [S]im ou [n]ao? ");
  445. read_string(input);
  446. } while (!strcasecmp(input, "S") && !strcasecmp(input, "N"));
  447. if (!strcasecmp(input, "S")) {
  448. // Selecionar um ou mais ьtens.
  449. form_items_insert(location, input);
  450. // Listar novamente
  451. puts_items_by_location(location, FALSE);
  452. }
  453. // Escrevendo no arquivo
  454. if (update_location(location)) {
  455. printf("Locacao atualizada com sucesso.\n");
  456. } else {
  457. printf("Locacao nao foi atualizada corretamente!\n");
  458. }
  459. printf("\n=======\n");
  460. free(location);
  461. }
  462. void form_location_search(char *input) {
  463. Location *location;
  464. // Antes de tudo, precisamos testar se hр alguma locaусo no arquivo
  465. if (locations_file_is_empty()) {
  466. printf(EMPTY_ERROR, __FILE__, "locacao");
  467. return;
  468. }
  469. printf("\n=======\nPESQUISANDO LOCACAO: \n\n");
  470. location = form_location_select(input);
  471. if (location->id == NON_EXIST) {
  472. free(location);
  473. return;
  474. }
  475. puts_location(location, TRUE);
  476. printf("\n=======\n");
  477. free(location);
  478. }
  479. void form_location_devolution(char *input) {
  480. Location *location;
  481. // Antes de tudo, precisamos testar se hр alguma locaусo no arquivo
  482. if (locations_file_is_empty()) {
  483. printf(EMPTY_ERROR, __FILE__, "locacao");
  484. return;
  485. }
  486. do {
  487. printf("\n=======\nDEVOLUCAO DE DVDs: \n\n");
  488. location = form_location_select(input);
  489. if (location->id == NON_EXIST) {
  490. free(location);
  491. return;
  492. }
  493. printf("\n>>>> SUMARIO DA LOCACAO <<<< \n\n");
  494. puts_location(location, TRUE);
  495. printf("-------------------------------------\n\n");
  496. } while (!be_sure(input));
  497. do {
  498. printf("> Deseja devolver todos os filme? [S]im ou [n]ao? ");
  499. read_string(input);
  500. } while (strcasecmp(input, "S") && strcasecmp(input, "N"));
  501. if (!strcasecmp(input, "S")) {
  502. printf("OK, agora resta pagar R$ %.2lf\n", get_total_to_pay(location));
  503. location_full_returned(location);
  504. } else {
  505. form_items_return(location, input);
  506. puts_items_by_location(location, FALSE);
  507. printf("OK, agora resta pagar R$ %.2lf\n", get_total_to_pay(location));
  508. }
  509. // Escrevendo no arquivo
  510. if (update_location(location)) {
  511. printf("Locacao atualizada com sucesso.\n");
  512. } else {
  513. printf("Locacao nao foi atualizada corretamente!\n");
  514. }
  515. printf("\n=======\n");
  516. free(location);
  517. }
  518. Location * form_location_select(char *input) {
  519. int id;
  520. Location *location;
  521. Client *client;
  522. location = location_malloc();
  523. do {
  524. printf("Digite [1] para pesquisar por ID ou [2] para pesquisar por cliente: ");
  525. read_string(input);
  526. switch (*input) {
  527. case '1':
  528. // Verifica se ж um ID vрlido
  529. id = check_by_id_location(input);
  530. if (id == NON_EXIST) {
  531. location->id = NON_EXIST;
  532. return location;
  533. }
  534. // Procura o location pelo ID
  535. location = search_location_by_id(id);
  536. *input = '1';
  537. break;
  538. case '2':
  539. // Pesquisa todo as locaушes relacionados ao cliente informado
  540. printf("\n=> Pesquisando cliente <=\n");
  541. client = form_client_select(input);
  542. // Verifica se ж um filme vрlido
  543. if (client->id == NON_EXIST) {
  544. free(client);
  545. location->id = NON_EXIST;
  546. return location;
  547. }
  548. // Lista todos as locaушes com o nome do cliente pesquisado.
  549. puts_all_locations_by_client(client);
  550. free(client);
  551. // Pede para o usuрrio escolher por ID agora.
  552. do {
  553. printf("> Qual deles? Informe o valor da coluna ID: ");
  554. read_string(input);
  555. } while (!validate_id(input));
  556. id = atoi(input);
  557. // Procura o location pelo ID agora
  558. location = search_location_by_id(id);
  559. *input = '2';
  560. break;
  561. default:
  562. printf("Opcao invalida!\n");
  563. }
  564. // Caso nсo ache, retorna com ID = NON_EXIST
  565. if (location->id == NON_EXIST) {
  566. if (*input == '1')
  567. printf(ID_NOT_FOUND_ERROR, __FILE__, "locacao");
  568. else if (*input == '2')
  569. printf(NAME_NOT_FOUND_ERROR, __FILE__, "locacao");
  570. location->id = NON_EXIST;
  571. return location;
  572. }
  573. } while (*input != '1' && *input != '2');
  574. return location;
  575. }
  576. void location_full_returned(Location *location) {
  577. FILE *file_stream = NULL;
  578. Item *item;
  579. // Antes de tudo, precisamos testar se hр algum item no arquivo
  580. if (items_file_is_empty()) {
  581. printf(EMPTY_ERROR, __FILE__, "item");
  582. return;
  583. }
  584. file_stream = fopen(LOCATIONS_FILEPATH, "rb+");
  585. if (!file_stream) {
  586. printf(READ_OPEN_ERROR, __FILE__, LOCATIONS_FILEPATH);
  587. exit(1);
  588. }
  589. item = item_malloc();
  590. fread(item, sizeof (Item), 1, file_stream);
  591. while (!feof(file_stream)) {
  592. if (item->id_location == location->id) {
  593. update_item_price(item);
  594. item->returned = TRUE;
  595. fseek(file_stream, -(sizeof (Item)), SEEK_CUR);
  596. fwrite(item, sizeof (Item), 1, file_stream);
  597. }
  598. fread(item, sizeof (Item), 1, file_stream);
  599. }
  600. fclose(file_stream);
  601. free(item);
  602. }