increment.rb 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. module Ticket::Number::Increment
  3. module_function
  4. def generate
  5. # get config
  6. config = Setting.get('ticket_number_increment')
  7. # read counter
  8. min_digs = config[:min_size] || 4
  9. counter_increment = nil
  10. Ticket::Counter.transaction do
  11. counter = Ticket::Counter.where(generator: 'Increment').lock(true).first
  12. if !counter
  13. counter = Ticket::Counter.new(generator: 'Increment', content: '0')
  14. end
  15. counter_increment = counter.content.to_i
  16. # increase counter
  17. counter_increment += 1
  18. # store new counter value
  19. counter.content = counter_increment.to_s
  20. counter.save
  21. end
  22. # fill up number counter
  23. if config[:checksum]
  24. min_digs = min_digs.to_i - 1
  25. end
  26. fillup = Setting.get('system_id').to_s || '1'
  27. 99.times do
  28. next if (fillup.length.to_i + counter_increment.to_s.length.to_i) >= min_digs.to_i
  29. fillup = fillup + '0'
  30. end
  31. number = fillup.to_s + counter_increment.to_s
  32. # calculate a checksum
  33. # The algorithm to calculate the checksum is derived from the one
  34. # Deutsche Bundesbahn (german railway company) uses for calculation
  35. # of the check digit of their vehikel numbering.
  36. # The checksum is calculated by alternately multiplying the digits
  37. # with 1 and 2 and adding the resulsts from left to right of the
  38. # vehikel number. The modulus to 10 of this sum is substracted from
  39. # 10. See: http://www.pruefziffernberechnung.de/F/Fahrzeugnummer.shtml
  40. # (german)
  41. if config[:checksum]
  42. chksum = 0
  43. mult = 1
  44. (1..number.length).each do |i|
  45. digit = number.to_s[i, 1]
  46. chksum = chksum + (mult * digit.to_i)
  47. mult += 1
  48. if mult == 3
  49. mult = 1
  50. end
  51. end
  52. chksum %= 10
  53. chksum = 10 - chksum
  54. if chksum == 10
  55. chksum = 1
  56. end
  57. number += chksum.to_s
  58. end
  59. number
  60. end
  61. def check(string)
  62. return if string.blank?
  63. # get config
  64. system_id = Setting.get('system_id') || ''
  65. ticket_hook = Setting.get('ticket_hook')
  66. ticket_hook_divider = Setting.get('ticket_hook_divider') || ''
  67. ticket = nil
  68. if Setting.get('ticket_number_ignore_system_id') == true
  69. system_id = ''
  70. end
  71. # probe format
  72. # NOTE: we use `(?<=\W|^)` at the start of the regular expressions below
  73. # because `\b` fails when ticket_hook begins with a non-word character (like '#')
  74. string.scan(/(?<=\W|^)#{Regexp.quote(ticket_hook)}#{Regexp.quote(ticket_hook_divider)}(#{system_id}\d{2,48})\b/i) do
  75. ticket = Ticket.find_by(number: $1)
  76. break if ticket
  77. end
  78. if !ticket
  79. string.scan(/(?<=\W|^)#{Regexp.quote(ticket_hook)}\s{0,2}(#{system_id}\d{2,48})\b/i) do
  80. ticket = Ticket.find_by(number: $1)
  81. break if ticket
  82. end
  83. end
  84. ticket
  85. end
  86. end