protokoll 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2011 YOURNAME
1
+ Copyright 2012 CELSO DANTAS
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -67,9 +67,36 @@ Ex:
67
67
 
68
68
  # will produce => "2011HOUSE00001", "2011HOUSE00002"...
69
69
 
70
+ == reserve_number!
71
+
72
+ object.reserve_number!
73
+
74
+ Add a new intance method colled: "your_instance#reserve_#{column_name}!".
75
+ With it you can reserve a number without the need to save it to the database. Ex:
76
+
77
+ car = Car.new
78
+ car.number
79
+ # => nil
80
+ car.reserve_number!
81
+ car.number
82
+ # => "CAR1100001"
83
+ # if you save it, the object will preserve the number: "CAR1100001"
84
+
85
+ It just increases the counter so any other object that gets saved or uses the #reserve_#{column_name} will get the next available number.
86
+
87
+ == Installation
88
+
89
+ Just add to the Gemfile:
90
+
91
+ gem 'protokoll'
92
+
93
+ And run _bundle install_ on the Rails application folder
94
+
95
+ bundle install
96
+
70
97
  == Questions & Sugestions
71
98
  This is my _first_ public gem, so if you have any questions os sugestions, feel free to contact me (use github msg system for that). It will be awesome to hear feedback to improve the code.
72
99
 
73
-
100
+ The gem is still on early _alpha_ so you may find bugs on it. And if you do, please use the _Issues_ here in Github and I'd love to fix it.
74
101
 
75
102
  This piece of software is free to use.
@@ -0,0 +1,24 @@
1
+ require 'rails/generators'
2
+
3
+ module Protokoll
4
+ module Generators
5
+ class MigrationGenerator < ::Rails::Generators::Base
6
+
7
+ include Rails::Generators::Migration
8
+
9
+ desc "Generate protokoll migration"
10
+ def create_migration_file
11
+ migration_name = "create_custom_auto_increments.rb"
12
+ migration_template migration_name, File.join('db', 'migrate', migration_name)
13
+ end
14
+
15
+ def self.source_root
16
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
17
+ end
18
+
19
+ def self.next_migration_number(path)
20
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ class CreateCustomAutoIncrements < ActiveRecord::Migration
2
+ def up
3
+ create_table :custom_auto_increments, :force => true do |t|
4
+ t.string :model_name
5
+ t.integer :counter, :default => 0
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :custom_auto_increment, :model_name
10
+ end
11
+
12
+ def down
13
+ drop_table :custom_auto_increment
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ require 'active_record'
2
+
3
+ module Protokoll
4
+ class Counter
5
+ def self.next(object, options)
6
+ element = Models::CustomAutoIncrement.find_or_create_by_model_name(object.class.to_s.underscore)
7
+
8
+ element.counter = 0 if outdated?(element, options)
9
+ element.counter += 1
10
+
11
+ element.save!
12
+
13
+ Formater.new.format(element.counter, options)
14
+ end
15
+
16
+ private
17
+
18
+ def self.outdated?(record, options)
19
+ Time.now.strftime(update_event(options)).to_i > record.created_at.strftime(update_event(options)).to_i
20
+ end
21
+
22
+ def self.update_event(options)
23
+ pattern = options[:pattern]
24
+ event = String.new
25
+
26
+ event += "%Y" if pattern.include? "%y" or pattern.include? "%Y"
27
+ event += "%m" if pattern.include? "%m"
28
+ event += "%H" if pattern.include? "%H"
29
+ event += "%M" if pattern.include? "%M"
30
+ event
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,79 @@
1
+
2
+ module Protokoll
3
+ class Formater
4
+ def format(number, options)
5
+ @options = options
6
+
7
+ build(number)
8
+ end
9
+
10
+ private
11
+
12
+ # gets the next number.
13
+ # it prepends the prefix + counter + sufix
14
+ # ex:
15
+ # "%Y####BANK"
16
+ # %Y => prefix (year)
17
+ # #### => counter (starts with 0001)
18
+ # BANK => sufix
19
+ #
20
+ # if we are in 2011, the first model to be saved will get "20110001BANK"
21
+ # the next model to be saved will get "20110002BANK", "20110003BANK"...
22
+ #
23
+ # number => is the counter
24
+ #
25
+ # next_custom_number(1)
26
+ # => "20110001BANK"
27
+ def build(number)
28
+ prefix(@options[:pattern]).to_s +
29
+ counter(@options[:pattern], number).to_s +
30
+ sufix(@options[:pattern]).to_s
31
+ end
32
+
33
+ def prefix(pattern)
34
+ prefx = extract_prefix(pattern)
35
+ expand_times(prefx.to_s)
36
+ end
37
+
38
+ def counter(pattern, n)
39
+ format_counter(digits_size(pattern), n)
40
+ end
41
+
42
+ def sufix(pattern)
43
+ sufx = extract_sufix(pattern)
44
+ expand_times(sufx.to_s)
45
+ end
46
+
47
+ def format_counter(zeros, value)
48
+ "%0#{zeros}d" % value
49
+ end
50
+
51
+ def extract_prefix(pattern)
52
+ # Company#### => Company
53
+ symbol = @options[:number_symbol]
54
+ (pattern =~ /^(\s|\d)*[^#{symbol}]+/ and $&)
55
+ end
56
+
57
+ def extract_sufix(pattern)
58
+ # ###Company => Company
59
+ symbol = @options[:number_symbol]
60
+ (pattern =~ /[^#{symbol}]+$/ and $&)
61
+ end
62
+
63
+ def expand_times(pattern)
64
+ pattern.sub!("%y", Time.now.strftime("%y"))
65
+ pattern.sub!("%Y", Time.now.strftime("%Y"))
66
+ pattern.sub!("%d", Time.now.strftime("%d"))
67
+ pattern.sub!("%m", Time.now.strftime("%m"))
68
+ pattern.sub!("%M", Time.now.strftime("%M"))
69
+ pattern.sub("%H", Time.now.strftime("%H"))
70
+ end
71
+
72
+ def digits_size(pattern)
73
+ symbol = @options[:number_symbol]
74
+ (pattern =~ /[#{symbol}]+/ and $&).length
75
+ end
76
+
77
+
78
+ end
79
+ end
@@ -0,0 +1,8 @@
1
+ require "active_record/base"
2
+
3
+ module Protokoll
4
+ module Models
5
+ class CustomAutoIncrement < ActiveRecord::Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,34 @@
1
+ module Protokoll
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+
6
+ # Class method available in models
7
+ #
8
+ # == Example
9
+ # class Order < ActiveRecord::Base
10
+ # protokoll :number
11
+ # end
12
+ #
13
+ def protokoll(column, _options = {})
14
+ options = { :pattern => "%Y%m#####",
15
+ :number_symbol => "#",
16
+ :column => column }
17
+
18
+ options.merge!(_options)
19
+
20
+ # Defining custom method
21
+ send :define_method, "reserve_#{options[:column]}!".to_sym do
22
+ self[column] = Counter.next(self, options)
23
+ end
24
+
25
+ # Signing before_create
26
+ before_create do |record|
27
+ return if record[column].present?
28
+
29
+ record[column] = Counter.next(self, options)
30
+ end
31
+ end
32
+ end
33
+
34
+ end
@@ -1,3 +1,3 @@
1
1
  module Protokoll
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/protokoll.rb CHANGED
@@ -1,39 +1,6 @@
1
- require "protokoll/auto_increment"
2
- require "protokoll/extract_number"
3
- require "protokoll/class_variable"
4
-
5
- module Protokoll
6
- extend ActiveSupport::Concern
7
-
8
- module ClassMethods
9
- def protokoll(column = nil, _options = {})
10
- ClassVariable.add_to self, :@@protokoll, :default => AutoIncrement.new
11
-
12
- prot = ClassVariable.get_from self, :@@protokoll
13
- return prot if column.nil?
14
-
15
- options = { :pattern => "%Y%m#####", :number_symbol => "#"}
16
- options.merge!(_options)
17
-
18
- prot.options = options
19
-
20
- before_create do |record|
21
- last = record.class.last
22
-
23
- if last.present?
24
- if prot.outdated?(last)
25
- prot.count = 0
26
- else
27
- prot.count = ExtractNumber.number(last[column], options[:pattern])
28
- end
29
- end
30
-
31
- prot.count += 1
32
- record[column] = prot.next_custom_number(column, prot.count)
33
- end
34
- end
35
- end
36
-
37
- end
1
+ require "protokoll/models/custom_auto_increment"
2
+ require "protokoll/formater"
3
+ require "protokoll/counter"
4
+ require "protokoll/protokoll"
38
5
 
39
6
  ActiveRecord::Base.send :include, Protokoll
@@ -0,0 +1,7 @@
1
+ # As I need to change the class a lot, I'm defining (and redefining tons of times)
2
+ # in the tests files.
3
+ # I'm just keeping the model here to make easy to understand what models
4
+ # are been used in the test.
5
+
6
+ # class Call < ActiveRecord::Base
7
+ # end
@@ -0,0 +1,7 @@
1
+ # As I need to change the class a lot, I'm defining (and redefining tons of times)
2
+ # in the tests files.
3
+ # I'm just keeping the model here to make easy to understand what models
4
+ # are been used in the test.
5
+
6
+ # class Protocol < ActiveRecord::Base
7
+ # end
Binary file
@@ -0,0 +1,15 @@
1
+ class CreateCustomAutoIncrements < ActiveRecord::Migration
2
+ def up
3
+ create_table :custom_auto_increments, :force => true do |t|
4
+ t.string :model_name
5
+ t.integer :counter, :default => 0
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :custom_auto_increments, :model_name
10
+ end
11
+
12
+ def down
13
+ drop_table :custom_auto_increments
14
+ end
15
+ end
@@ -11,24 +11,33 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20110928013630) do
14
+ ActiveRecord::Schema.define(:version => 20120222164124) do
15
15
 
16
16
  create_table "calls", :force => true do |t|
17
17
  t.string "number"
18
- t.datetime "created_at"
19
- t.datetime "updated_at"
18
+ t.datetime "created_at", :null => false
19
+ t.datetime "updated_at", :null => false
20
20
  end
21
21
 
22
+ create_table "custom_auto_increments", :force => true do |t|
23
+ t.string "model_name"
24
+ t.integer "counter", :default => 0
25
+ t.datetime "created_at", :null => false
26
+ t.datetime "updated_at", :null => false
27
+ end
28
+
29
+ add_index "custom_auto_increments", ["model_name"], :name => "index_custom_auto_increments_on_model_name"
30
+
22
31
  create_table "principals", :force => true do |t|
23
32
  t.string "protokoll_number"
24
- t.datetime "created_at"
25
- t.datetime "updated_at"
33
+ t.datetime "created_at", :null => false
34
+ t.datetime "updated_at", :null => false
26
35
  end
27
36
 
28
37
  create_table "protocols", :force => true do |t|
29
38
  t.string "number"
30
- t.datetime "created_at"
31
- t.datetime "updated_at"
39
+ t.datetime "created_at", :null => false
40
+ t.datetime "updated_at", :null => false
32
41
  end
33
42
 
34
43
  end
Binary file