oujoke 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +53 -0
- data/lib/oujoke.rb +3 -0
- data/lib/queue/helper.rb +43 -0
- data/lib/queue/processor.rb +16 -0
- data/lib/queue/publisher.rb +21 -0
- data/lib/workflow/base.rb +82 -0
- data/lib/workflow/business_process.rb +31 -0
- data/lib/workflow/errors.rb +16 -0
- data/lib/workflow/transition.rb +20 -0
- data/lib/workflow/transitions/approve_transition.rb +17 -0
- data/lib/workflow/transitions/forward_transition.rb +21 -0
- data/lib/workflow/transitions/mark_paid_transition.rb +13 -0
- data/lib/workflow/transitions/reject_transition.rb +16 -0
- data/lib/workflow/transitions/revoke_transition.rb +16 -0
- data/lib/workflow/transitions/serial_approve_transition.rb +17 -0
- data/lib/workflow.rb +39 -0
- data/test/forward_transition_test.rb +38 -0
- data/test/helper.rb +108 -0
- data/test/test_oujoke.rb +37 -0
- metadata +98 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Dieinzige
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= oujoke
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Dieinzige. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "oujoke"
|
8
|
+
gem.summary = %Q{Simple helpers for workflow organizations}
|
9
|
+
gem.description = %Q{Simple helpers for workflow organizations}
|
10
|
+
gem.email = "dieinzige@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/Dieinzige/oujoke"
|
12
|
+
gem.authors = ["Dieinzige"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "oujoke #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/lib/oujoke.rb
ADDED
data/lib/queue/helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'mq'
|
2
|
+
module Oujoke
|
3
|
+
module InvoiceQueue
|
4
|
+
module Helper
|
5
|
+
def log message
|
6
|
+
puts "#{MQ.id}: #{message}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def logp *args
|
10
|
+
print args
|
11
|
+
$stdout.flush
|
12
|
+
end
|
13
|
+
|
14
|
+
def graceful_death
|
15
|
+
AMQP.stop{ EM.stop }
|
16
|
+
exit(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def serialize data
|
22
|
+
Marshal.dump(data)
|
23
|
+
end
|
24
|
+
|
25
|
+
def unserialize data
|
26
|
+
autoload_missing_constants do
|
27
|
+
Marshal.load data
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def autoload_missing_constants
|
32
|
+
yield
|
33
|
+
rescue ArgumentError => error
|
34
|
+
lazy_load ||= Hash.new {|hash, hash_key| hash[hash_key] = true; false}
|
35
|
+
if error.to_s[/undefined class|referred/] && !lazy_load[error.to_s.split.last.constantize]
|
36
|
+
retry
|
37
|
+
else
|
38
|
+
raise error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module InvoiceQueue
|
3
|
+
class Processor
|
4
|
+
include Oujoke::InvoiceQueue::Helper
|
5
|
+
|
6
|
+
#Call process on selected queue
|
7
|
+
def self.run_process(queue, &block)
|
8
|
+
queue.subscribe(:ack => true) { |headers, payload|
|
9
|
+
data = unserialize(payload)
|
10
|
+
block.call(data)
|
11
|
+
headers.ack
|
12
|
+
}
|
13
|
+
end # end run process
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module InvoiceQueue
|
3
|
+
class Publisher
|
4
|
+
include Oujoke::InvoiceQueue::Helper
|
5
|
+
|
6
|
+
#Call process on selected queue
|
7
|
+
def publish(queue_name, object)
|
8
|
+
amq = MQ.new
|
9
|
+
amq.queue(queue_name).publish(serialize(object))
|
10
|
+
end # end run process
|
11
|
+
|
12
|
+
def amqp_send(queue_name, object)
|
13
|
+
AMQP.start do
|
14
|
+
amq = MQ.new
|
15
|
+
amq.queue(queue_name).publish(serialize(object))
|
16
|
+
AMQP.stop { EM.stop }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class Base
|
4
|
+
attr_accessor :attributes
|
5
|
+
attr_accessor :invoice_id
|
6
|
+
|
7
|
+
def self.construct(json_obj)
|
8
|
+
new(json_obj)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(base_obj)
|
12
|
+
@raw_obj = base_obj
|
13
|
+
@attributes = {}
|
14
|
+
@transitions = []
|
15
|
+
call_parser_stack
|
16
|
+
end
|
17
|
+
|
18
|
+
def invoice_id
|
19
|
+
@invoice_id || @attributes["data"]["invoice_id"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def invoice_id=(v)
|
23
|
+
@attributes["data"]["invoice_id"] = v
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def initiator_email=(v)
|
28
|
+
@attributes["data"]["initiator_email"] = v
|
29
|
+
end
|
30
|
+
|
31
|
+
def initiator_email
|
32
|
+
@attributes["data"]["initiator_email"]
|
33
|
+
end
|
34
|
+
|
35
|
+
#Get all states in ordered position
|
36
|
+
def states
|
37
|
+
@attributes["data"]["states"]
|
38
|
+
end
|
39
|
+
|
40
|
+
#Return current state
|
41
|
+
def current_state
|
42
|
+
@attributes["data"]["current_state"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def current_state=(v)
|
46
|
+
@attributes["data"]["current_state"] = v
|
47
|
+
end
|
48
|
+
|
49
|
+
def transition_params(transition_name , params)
|
50
|
+
@attributes["data"]["transitions"].each do |t|
|
51
|
+
t["params"] = params if t["name"] = transaction_name
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def transitions
|
56
|
+
@transitions
|
57
|
+
end
|
58
|
+
|
59
|
+
def callable_transition
|
60
|
+
@transitions.detect{|t| t.from_state == current_state }
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
#Return current business process data as json
|
65
|
+
#
|
66
|
+
def persistanse_data
|
67
|
+
@attributes.to_json
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_state(state)
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
def call_parser_stack
|
75
|
+
@attributes = ActiveSupport::JSON.decode(@raw_obj)
|
76
|
+
@attributes["data"]["transitions"].each do |t|
|
77
|
+
@transitions << "Oujoke::Workflow::#{t["name"].camelize}".constantize.new(self,t)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
module BusinessProcess
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
|
11
|
+
def start
|
12
|
+
self.current_state = "initialized_state"
|
13
|
+
self.workflow_data.current_state = "initialized_state"
|
14
|
+
self.raw_workflow = self.workflow_data.persistanse_data
|
15
|
+
self.save
|
16
|
+
Oujoke::InvoiceQueue::Publisher.new.publish("workflow-initialized_state" , self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def workflow_data
|
20
|
+
@_workflow_data ||= Oujoke::Workflow::Base.new(self.raw_workflow)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(receiver)
|
25
|
+
raise NonPersistenseModel unless receiver.new.respond_to?(:raw_workflow)
|
26
|
+
receiver.extend ClassMethods
|
27
|
+
receiver.send :include, InstanceMethods
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class OujokeError < StandardError
|
2
|
+
|
3
|
+
end
|
4
|
+
|
5
|
+
# Raise if model not respond to persistense models
|
6
|
+
class NonPersistenseModel < OujokeError
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
class DeserializationError < OujokeError
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
class InvoiceNonSpecified < OujokeError
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class Transition
|
4
|
+
attr_accessor :from_state , :to_state, :on_raise , :name , :params , :workflow
|
5
|
+
|
6
|
+
def initialize(bp,options = {})
|
7
|
+
@from_state = options["from_state"]
|
8
|
+
@to_state = options["to_state"]
|
9
|
+
@on_raise = options["on_raise"]
|
10
|
+
@name = options["name"]
|
11
|
+
@params = options["params"]
|
12
|
+
@business_process = bp
|
13
|
+
end
|
14
|
+
|
15
|
+
def perform
|
16
|
+
raise "Should be override to perform"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class ApproveTransition < Transition
|
4
|
+
def perform
|
5
|
+
@bill = Bill.find(@workflow.bill_id)
|
6
|
+
@bill.comments.create(:body => @params["comment"], :base_contact => @workflow.initiator_email) unless @params["comment"].blank?
|
7
|
+
@emails = @params["recipient_emails"]
|
8
|
+
@bill.events.create(:message =>"#{@workflow.initiator_email} переслал для визирования #{@emails.join(" , ")}")
|
9
|
+
@emails.each do |e|
|
10
|
+
permission = ApproverPermission.create(:bill_id => @bill.id , :base_contact => e )
|
11
|
+
Notifier.deliver_approve_bill(:bill => @bill, :permission => permission , :comment => @params["comment"] )
|
12
|
+
end
|
13
|
+
@workflow.current_state = @params["to_state"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class ForwardTransition < Transition
|
4
|
+
|
5
|
+
def perform
|
6
|
+
@invoice = Invoice.find(@business_process.invoice_id)
|
7
|
+
permissions = @invoice.permissions.where(:type => "HolderPermission").includes(:contact).all.select{|v| v.contact.value == @workflow.initiator_email }
|
8
|
+
permissions.each{|p| p.destroy}
|
9
|
+
ViewerPermission.create!(:invoice_id => @invoice.id, :_contact => @workflow.initiator_email)
|
10
|
+
@params["recipient_contacts"].each do |contact|
|
11
|
+
permission = HolderPermission.create!(:invoice_id => @invoice.id, :_contact => contact)
|
12
|
+
FlexibilityNotifier.new(permission.contact, :name => :forward_invoice,
|
13
|
+
:permission => permission.id, :invoice => id, :comment => @params["comment"]).perform
|
14
|
+
end
|
15
|
+
@invoice.comments.create(:body => @params["comment"],:_contact => @workflow.initiator_email) unless @params["comment"].blank?
|
16
|
+
@business_process.to_state(@params["to_state"])
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class MarkPaidTransition < Transition
|
4
|
+
def perform
|
5
|
+
@invoice = Invoice.find(@workflow.invoice_id)
|
6
|
+
# @invoice.events.create(:message =>"#{@workflow.initiator_email} пометил счет как оплаченный")
|
7
|
+
@invoice.comments.create(:body => @params["comment"],:_contact => @workflow.initiator_email) unless @params["comment"].blank?
|
8
|
+
Notifier.deliver_mark_as_paid(:bill => @bill, :comment => @params["comment"] , :base_contact => @workflow.initiator_email)
|
9
|
+
@workflow.current_state = @params["to_state"]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class RejectTransition < Transition
|
4
|
+
|
5
|
+
def perform
|
6
|
+
@bill = Bill.find(@workflow.bill_id)
|
7
|
+
@bill.reject
|
8
|
+
@bill.events.create(:message =>"#{@workflow.initiator_email} отказался оплачивать")
|
9
|
+
@bill.comments.create(:body => @params["comment"],:base_contact => @workflow.initiator_email) unless @params["comment"].blank?
|
10
|
+
Notifier.deliver_reject_bill(:bill => @bill , :comment => @params["comment"])
|
11
|
+
@workflow.current_state = @params["to_state"]
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class RevokeTransition < Transition
|
4
|
+
|
5
|
+
def perform
|
6
|
+
@bill = Bill.find(@workflow.bill_id)
|
7
|
+
@bill.revoke
|
8
|
+
@bill.events.create(:message =>"#{@bill.sender} отозвал счет")
|
9
|
+
@bill.comments.create(:body => @params["comment"],:base_contact => @workflow.initiator_email) unless @params["comment"].blank?
|
10
|
+
Notifier.deliver_revoke_bill(:bill => @bill , :comment => @params["comment"])
|
11
|
+
@workflow.current_state = @params["to_state"]
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
class SerialApproveTransition < Transition
|
4
|
+
|
5
|
+
def perform
|
6
|
+
@invoice = Invoice.find(@workflow.invoice_id)
|
7
|
+
# @bill.events.create(:message =>"#{@bill.sender} отозвал счет")
|
8
|
+
@invoice.comments.create(:body => @params["comment"],:_contact => @workflow.initiator_email) unless @params["comment"].blank?
|
9
|
+
|
10
|
+
FlexibilityNotifier.new(permission.contact, :name => :serial, :permission => permission.id , :invoice => id).perform
|
11
|
+
Notifier.deliver_revoke_bill(:bill => @bill , :comment => @params["comment"])
|
12
|
+
@workflow.current_state = @params["to_state"]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/workflow.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Oujoke
|
2
|
+
module Workflow
|
3
|
+
|
4
|
+
%w(base transition errors business_process).each do |base_req|
|
5
|
+
require File.dirname(__FILE__) + "/workflow/#{base_req}"
|
6
|
+
end
|
7
|
+
|
8
|
+
%w(approve mark_paid reject approve revoke forward).each do |transition|
|
9
|
+
require File.dirname(__FILE__) + "/workflow/transitions/#{transition}_transition"
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
#
|
18
|
+
#Create businessprocess , with filled data
|
19
|
+
#then after-create will be notify MQ-queue that we have one new BP, witch should be performed
|
20
|
+
#
|
21
|
+
def start(options = {})
|
22
|
+
#todo validation for main optons
|
23
|
+
bp = options[:klass].new(:workflow_id => self.id , :_contact => options[:_contact], :raw_workflow => options[:data] , :invoice_id => options[:invoice_id])
|
24
|
+
bp.current_state = "created_state"
|
25
|
+
bp.save!
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.included(receiver)
|
31
|
+
raise NonPersistenseModel unless receiver.new.respond_to?(:raw_workflow)
|
32
|
+
receiver.extend ClassMethods
|
33
|
+
receiver.send :include, InstanceMethods
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestForwardTransition < Test::Unit::TestCase
|
4
|
+
context "construct_from_json" do
|
5
|
+
setup do
|
6
|
+
@invoice = Invoice.create(:base_contact => 'talala@mail.ru')
|
7
|
+
@json_str ="{'name' : 'forward' , 'data' : {
|
8
|
+
'invoice_id' : #{@invoice.id},
|
9
|
+
'current_state': 'initialized',
|
10
|
+
'initiator_email' : #{@invoice.base_contact},
|
11
|
+
'states' : [
|
12
|
+
{'1' : 'created'},
|
13
|
+
{'2' : 'initialized'},
|
14
|
+
{'3' : 'sended'}
|
15
|
+
],
|
16
|
+
'transitions' : [
|
17
|
+
{
|
18
|
+
'name' : 'forward_transition' ,
|
19
|
+
'from_state' : 'initialized' ,
|
20
|
+
'to_state' : 'finished_state' ,
|
21
|
+
'on_raise' : '',
|
22
|
+
'params' : { 'recipient_contacts' : 'vasya_pupkin@gmail.com' }
|
23
|
+
}
|
24
|
+
]
|
25
|
+
}
|
26
|
+
}"
|
27
|
+
@business_process = Oujoke::Workflow::Base.construct(@json_str)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "after call transactions holders count should not be increment" do
|
31
|
+
assert ! @business_process.callable_transition.nil?
|
32
|
+
holders_count = @invoice
|
33
|
+
@business_process.callable_transition.perform
|
34
|
+
assert
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'active_record'
|
4
|
+
gem 'sqlite3-ruby'
|
5
|
+
require 'shoulda'
|
6
|
+
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
10
|
+
require 'oujoke'
|
11
|
+
|
12
|
+
class Test::Unit::TestCase
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => '/tmp/workflows.sqlite')
|
21
|
+
ActiveRecord::Migration.verbose = false
|
22
|
+
ActiveRecord::Base.default_timezone = :utc if Time.zone.nil?
|
23
|
+
|
24
|
+
ActiveRecord::Schema.define do
|
25
|
+
|
26
|
+
create_table :workflow, :force => true do |t|
|
27
|
+
t.string :name
|
28
|
+
t.string :description
|
29
|
+
t.text :raw_workflow
|
30
|
+
t.timestamp :deleted_at, :default => nil
|
31
|
+
end
|
32
|
+
|
33
|
+
create_table :business_process, :force => true do |t|
|
34
|
+
t.string :current_state , :limit => 200
|
35
|
+
t.text :raw_workflow
|
36
|
+
t.integer :bill_id
|
37
|
+
end
|
38
|
+
create_table :invoices, :force => true do |t|
|
39
|
+
t.string :base_contact , :limit => 200
|
40
|
+
t.string :state
|
41
|
+
end
|
42
|
+
create_table :permissions, :force => true do |t|
|
43
|
+
t.string :type , :limit => 200
|
44
|
+
t.string :_contact
|
45
|
+
t.text :bill_id
|
46
|
+
end
|
47
|
+
create_table :workflows, :force => true do |t|
|
48
|
+
t.string :name
|
49
|
+
t.string :description
|
50
|
+
t.reference :user
|
51
|
+
t.text :raw_workflow
|
52
|
+
t.timestamps
|
53
|
+
end
|
54
|
+
create_table :business_processes, :force => true do |t|
|
55
|
+
t.timestamp :deleted_at, :default => nil
|
56
|
+
t.string :current_state , :limit => 200
|
57
|
+
t.text :raw_workflow
|
58
|
+
t.reference :workflow
|
59
|
+
t.reference :bill
|
60
|
+
t.timestamps
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
class Invoice < ActiveRecord::Base
|
65
|
+
has_many :permissions
|
66
|
+
after_create :create_permission
|
67
|
+
|
68
|
+
def holders
|
69
|
+
permissions.select {|p| p.is_a?(HolderPermission)}
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
def create_permission
|
74
|
+
HolderPermission.create(:invoice_id => id, :_contact =.)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Permission < ActiveRecord::Base
|
79
|
+
belongs_to :bill
|
80
|
+
end
|
81
|
+
|
82
|
+
class HolderPermission < Permission
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
class ViewPermission < Permission
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
class ApprovePermission < Permission
|
91
|
+
|
92
|
+
end
|
93
|
+
class MerchantPermission < Permission
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
class Workflow < ActiveRecord::Base
|
98
|
+
has_many :business_process
|
99
|
+
belongs_to :user
|
100
|
+
include Oujoke::Workflow
|
101
|
+
end
|
102
|
+
|
103
|
+
class BusinessProcess < ActiveRecord::Base
|
104
|
+
belongs_to :invoice
|
105
|
+
belongs_to :workflow
|
106
|
+
include Oujoke::Workflow::BusinessProcess
|
107
|
+
end
|
108
|
+
|
data/test/test_oujoke.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestOujoke < Test::Unit::TestCase
|
4
|
+
context "construct_from_json" do
|
5
|
+
setup do
|
6
|
+
@invoice = Invoice.create(:base_contact => 'talala@mail.ru')
|
7
|
+
@json_str ="{'name' : 'approve' , 'data' : {
|
8
|
+
'invoice_id' : #{@invoice.id},
|
9
|
+
'current_state': 'initialized',
|
10
|
+
'initiator_email' : #{@invoice.base_contact},
|
11
|
+
'states' : [
|
12
|
+
{'1' : 'created'},
|
13
|
+
{'2' : 'initialized'},
|
14
|
+
{'3' : 'sended'}
|
15
|
+
],
|
16
|
+
'transitions' : [
|
17
|
+
{
|
18
|
+
'name' : 'approve_transition' ,
|
19
|
+
'from_state' : 'initialized' ,
|
20
|
+
'to_state' : 'finished_state' ,
|
21
|
+
'on_raise' : '',
|
22
|
+
'params' : { 'recipient_contacts' : 'vasya_pupkin@gmail.com' }
|
23
|
+
}
|
24
|
+
]
|
25
|
+
}
|
26
|
+
}"
|
27
|
+
@business_process = Oujoke::Workflow::Base.construct(@json_str)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "should find callable transitions" do
|
31
|
+
assert !@business_process.transitions.empty?
|
32
|
+
assert @business_process.transitions.size == 1
|
33
|
+
assert @business_process.transitions.first == @business_process.callable_transition
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oujoke
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Dieinzige
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-22 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: thoughtbot-shoulda
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
description: Simple helpers for workflow organizations
|
33
|
+
email: dieinzige@gmail.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- LICENSE
|
40
|
+
- README.rdoc
|
41
|
+
files:
|
42
|
+
- .document
|
43
|
+
- .gitignore
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
- Rakefile
|
47
|
+
- lib/oujoke.rb
|
48
|
+
- lib/queue/helper.rb
|
49
|
+
- lib/queue/processor.rb
|
50
|
+
- lib/queue/publisher.rb
|
51
|
+
- lib/workflow.rb
|
52
|
+
- lib/workflow/base.rb
|
53
|
+
- lib/workflow/business_process.rb
|
54
|
+
- lib/workflow/errors.rb
|
55
|
+
- lib/workflow/transition.rb
|
56
|
+
- lib/workflow/transitions/approve_transition.rb
|
57
|
+
- lib/workflow/transitions/forward_transition.rb
|
58
|
+
- lib/workflow/transitions/mark_paid_transition.rb
|
59
|
+
- lib/workflow/transitions/reject_transition.rb
|
60
|
+
- lib/workflow/transitions/revoke_transition.rb
|
61
|
+
- lib/workflow/transitions/serial_approve_transition.rb
|
62
|
+
- test/forward_transition_test.rb
|
63
|
+
- test/helper.rb
|
64
|
+
- test/test_oujoke.rb
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: http://github.com/Dieinzige/oujoke
|
67
|
+
licenses: []
|
68
|
+
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options:
|
71
|
+
- --charset=UTF-8
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.3.6
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Simple helpers for workflow organizations
|
95
|
+
test_files:
|
96
|
+
- test/forward_transition_test.rb
|
97
|
+
- test/helper.rb
|
98
|
+
- test/test_oujoke.rb
|