Created
April 9, 2014 19:56
-
-
Save davinmsu/10308212 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Order < ActiveRecord::Base | |
| belongs_to :user | |
| has_many :processed_orders | |
| has_many :operations | |
| has_many :documents, as: :reference | |
| include HTTParty | |
| base_uri ENV['VK_API_HOST'] | |
| enum type: { | |
| unknown: 0, | |
| like: 1, | |
| share: 2, | |
| join: 3 | |
| } | |
| enum status: { | |
| inactive: 0, | |
| active: 1, | |
| pending: 2, | |
| completed_by_date: 3, | |
| completed_by_count: 4, | |
| cancelled_by_user: 5, | |
| cancelled_by_object: 6, | |
| cancelled_by_admin: 7, | |
| completed: 8 | |
| } | |
| enum obj_owner_type: { | |
| vk_user: 0, | |
| vk_group: 1 | |
| } | |
| before_create :get_obj_details | |
| after_create :activate! | |
| enum_features :type, :status, :obj_owner_type | |
| scope :exclude_processed, -> (user = nil) do | |
| unless user.nil? | |
| where(ProcessedOrder.where('order_id = orders.id AND user_id = ?', user.id).exists.not) | |
| end | |
| end | |
| def accept(user) | |
| inactive! and return if self.user.accounts.current.first.balance < price | |
| processed_orders.create user: user | |
| operations.create! user: user | |
| increment!(:monitoring_operations_count, 1) | |
| pending! unless monitoring_operations_count < count | |
| end | |
| def decline(user) | |
| self.processed_orders.create user: user, status: :declined | |
| end | |
| def self.get_available(user) | |
| a = exclude_processed(user).order(price: :desc) | |
| x = 1 | |
| sum = (a.pluck(:price).collect { |b| b**x }).sum | |
| weights = a.collect { |e| (e.price)**x/sum.to_f } | |
| r = rand(1000).to_f/1000 | |
| k = 0 | |
| weights.each_with_index do |e,i| | |
| k += e | |
| return (a[i]) if k > r | |
| end | |
| nil | |
| end | |
| def set_to_pending_by_time | |
| pending! if inactive? || active? | |
| completed! if pending? && operations.empty? | |
| end | |
| # private | |
| def activate! | |
| self.delay(run_at: self.active_from).active! | |
| self.delay(run_at: self.active_to).set_to_pending_by_time | |
| self.delay(run_at: 20.seconds.from_now).check_object | |
| self.delay(run_at: 20.seconds.from_now).check_operations | |
| (get_vk_contractors & User.all.pluck(:ext_id)).each { |u| processed_orders.create user: User.find_by(ext_id: u), status: :existed } | |
| end | |
| def get_vk_contractors | |
| users = [] | |
| method = 'likes.getList' if like? || share? | |
| method = 'groups.getMembers' if join? | |
| params = set_vk_params | |
| loop do | |
| response = self.class.get("/#{method}", query: params) | |
| users.concat response['response']['users'] | |
| break if response['response']['users'].empty? | |
| params.merge! offset: params[:offset] += (Rails.configuration.vk_request_count - Rails.configuration.vk_request_overlay) | |
| end | |
| users | |
| end | |
| def set_vk_params | |
| params = {count: Rails.configuration.vk_request_count, offset: 0} | |
| if like? || share? | |
| params.merge! type: :post, | |
| owner_id: vk_group? ? obj_owner_id * -1 : obj_owner_id, | |
| item_id: obj_item_id, | |
| friends_only: 0 | |
| end | |
| params.merge! filter: :likes if like? | |
| params.merge! filter: :copies if share? | |
| params.merge! group_id: obj_owner_id if join? | |
| params | |
| end | |
| def check_object | |
| query = {posts: "#{(vk_group? ? '-' : '')}#{obj_owner_id}_#{obj_item_id}"} | |
| cancelled_by_object! if self.class.get('/wall.getById', query: query)['response'].empty? | |
| operations.each { |o| o.confirm } | |
| self.delay(run_at: 20.seconds.from_now).check_operations if monitoring || pending? | |
| end | |
| def check_operations | |
| operations.monitoring.where(user_id: operations.monitoring.pluck(:user_id) - get_vk_contractors).each { |o| o.fail } | |
| self.delay(run_at: 20.seconds.from_now).check_operations if monitoring || pending? | |
| end | |
| def get_obj_details | |
| key = obj_url.match(/wall-?[0-9]+_[0-9]+/).to_s | |
| return if key.blank? | |
| self.obj_owner_type = :vk_group if key =~ /\Awall-/ | |
| self.obj_owner_id = key[/[0-9]+_/].gsub(/_/, '').to_i | |
| self.obj_item_id = key[/_[0-9]+\Z/].gsub(/_/, '').to_i | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment