Class: BlackStack::Client
- Inherits:
-
Object
- Object
- BlackStack::Client
- Defined in:
- lib/extend_client_by_invoicing_payments_processing.rb
Instance Method Summary collapse
- #add_bonus(id_user_creator, product_code, bonus_credits, description, expiration_time) ⇒ Object
-
#adjustment(product_code, adjustment_amount = 0, adjustment_credits = 0, description = nil, type = BlackStack::Movement::MOVEMENT_TYPE_ADJUSTMENT, registraton_time = nil) ⇒ Object
crea un registro en la tabla movment, reduciendo la cantidad de creditos con saldo importe 0, para el producto indicado en product_code.
-
#bonus(product_code, expiration, number_of_credits = 1, description = nil) ⇒ Object
crea un registro en la tabla movment, reduciendo la cantidad de creditos con saldo importe 0, para el producto indicado en product_code.
-
#consume(product_code, number_of_credits = 1, description = nil, datetime = nil) ⇒ Object
crea/actualiza un registro en la tabla movment, reduciendo la cantidad de creditos y saldo que tiene el cliente, para el producto indicado en product_code.
-
#deserve_trial ⇒ Object
retorna true si este cliente no tiene ninguna generada con productos LGB2.
- #deserve_trial? ⇒ Boolean
-
#division ⇒ Object
TODO: el cliente deberia tener una FK a la tabla division.
- #get_balance ⇒ Object
- #get_movements(from_time, to_time, product_code = nil) ⇒ Object
-
#has_item(item_number, amount = nil) ⇒ Object
retorna true si existe algun item de factura relacionado al ‘plan’ (‘item_number’).
-
#movements ⇒ Object
This method replace the line: one_to_many :movements, :class=>:‘BlackStack::Movement’, :key=>:id_client.
-
#plans ⇒ Object
retorna los planes estandar definidos en el array BlackStack::InvoicingPaymentsProcessing::plans_descriptor, y le concatena los arrays customizados de este cliente definidos en la tabla custom_plan.
-
#recalculate(product_code) ⇒ Object
recalculate the amount for all the consumptions, expirations, and adjustments.
-
#stat_balance_delay_minutes ⇒ Object
how many minutes ago should have updated the table stat_balance with the amount and credits of this client, for each product.
-
#update_stat_balance(product_code = nil) ⇒ Object
update the table stat_balance with the amount and credits of this client, for each product.
Instance Method Details
#add_bonus(id_user_creator, product_code, bonus_credits, description, expiration_time) ⇒ Object
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 307 def add_bonus(id_user_creator, product_code, bonus_credits, description, expiration_time) bonus_amount = 0 # balance = BlackStack::Balance.new(self.id, product_code) # amount = balance.amount.to_f # credits = balance.credits.to_f # if amount>=0 && credits>=0 # bonus_amount = (amount / credits) * bonus_credits ## else ## h = BlackStack::InvoicingPaymentsProcessing.product_descriptor(product_code) ## bonus_amount = h[:default_fee_per_unit].to_f # end m = BlackStack::Movement.new( :id_client => self.id, :create_time => now(), :type => BlackStack::Movement::MOVEMENT_TYPE_ADD_BONUS, :id_user_creator => id_user_creator, :description => description, :paypal1_amount => 0, :bonus_amount => bonus_amount, :amount => 0-bonus_amount, :credits => 0-bonus_credits, :profits_amount => 0, :product_code => product_code, :expiration_time => expiration_time ) m.id = guid() m.save end |
#adjustment(product_code, adjustment_amount = 0, adjustment_credits = 0, description = nil, type = BlackStack::Movement::MOVEMENT_TYPE_ADJUSTMENT, registraton_time = nil) ⇒ Object
crea un registro en la tabla movment, reduciendo la cantidad de creditos con saldo importe 0, para el producto indicado en product_code.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 151 def adjustment(product_code, adjustment_amount=0, adjustment_credits=0, description=nil, type=BlackStack::Movement::MOVEMENT_TYPE_ADJUSTMENT, registraton_time=nil) adjust = BlackStack::Movement.new adjust.id = guid() adjust.id_client = self.id adjust.create_time = registraton_time.nil? ? now() : registraton_time adjust.type = type adjust.description = description.nil? ? 'Adjustment' : description adjust.paypal1_amount = 0 adjust.bonus_amount = 0 adjust.amount = adjustment_amount adjust.credits = adjustment_credits adjust.profits_amount = -adjustment_amount adjust.product_code = product_code adjust.expiration_time = nil adjust.save adjust end |
#bonus(product_code, expiration, number_of_credits = 1, description = nil) ⇒ Object
crea un registro en la tabla movment, reduciendo la cantidad de creditos con saldo importe 0, para el producto indicado en product_code.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 127 def bonus(product_code, expiration, number_of_credits=1, description=nil) bonus_amount = 0 # Los bonos siempre son por un importa igual a 0. bonus = BlackStack::Movement.new bonus.id = guid() bonus.id_client = self.id bonus.create_time = now() bonus.type = BlackStack::Movement::MOVEMENT_TYPE_ADD_BONUS bonus.description = description.nil? ? 'Bonus' : description bonus.paypal1_amount = 0 bonus.bonus_amount = bonus_amount bonus.amount = -bonus_amount bonus.credits = -number_of_credits bonus.profits_amount = 0 bonus.product_code = product_code bonus.expiration_time = expiration bonus.save # recalculate - CANCELADO #bonus.recalculate # return bonus end |
#consume(product_code, number_of_credits = 1, description = nil, datetime = nil) ⇒ Object
crea/actualiza un registro en la tabla movment, reduciendo la cantidad de creditos y saldo que tiene el cliente, para el producto indicado en product_code.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 90 def consume(product_code, number_of_credits=1, description=nil, datetime=nil) dt = datetime.nil? ? now() : datetime.to_time.to_sql # create the consumtion total_credits = 0.to_f - BlackStack::Balance.new(self.id, product_code).credits.to_f total_amount = 0.to_f - BlackStack::Balance.new(self.id, product_code).amount.to_f ratio = total_credits == 0 ? 0.to_f : total_amount.to_f / total_credits.to_f amount = number_of_credits.to_f * ratio cons = BlackStack::Movement.new cons.id = guid() cons.id_client = self.id cons.create_time = dt cons.type = BlackStack::Movement::MOVEMENT_TYPE_CANCELATION cons.description = description.nil? ? 'Consumption' : description cons.paypal1_amount = 0 cons.bonus_amount = 0 cons.amount = amount cons.credits = number_of_credits cons.profits_amount = -amount cons.product_code = product_code cons.expiration_time = nil cons.save # if there is negative credits prod = BlackStack::InvoicingPaymentsProcessing.product_descriptor(product_code) total_credits = 0.to_f - BlackStack::Balance.new(self.id, product_code).credits.to_f total_amount = 0.to_f - BlackStack::Balance.new(self.id, product_code).amount.to_f sleep(2) # delay to ensure the time of the bonus movement will be later than the time of the consumption movement if total_credits < 0 self.adjustment(product_code, total_amount, total_credits, 'Adjustment Because Quota Has Been Exceeded (1).') end # recaculate amounts in both consumptions and expirations - CANCELADO - Se debe hacer offline #self.recalculate(product_code) # return cons end |
#deserve_trial ⇒ Object
retorna true si este cliente no tiene ninguna generada con productos LGB2
222 223 224 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 222 def deserve_trial() self.disabled_for_trial_ssm != true end |
#deserve_trial? ⇒ Boolean
227 228 229 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 227 def deserve_trial? self.deserve_trial() end |
#division ⇒ Object
TODO: el cliente deberia tener una FK a la tabla division. La relacion no puede ser N-N. TODO: se debe preguntar a la central
210 211 212 213 214 215 216 217 218 219 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 210 def division q = "SELECT d.id as id " + "FROM division d " + "JOIN user_division ud ON d.id=ud.id_division " + "JOIN [user] u ON u.id=ud.id_user " + "WHERE u.id_client = '#{self.id}' " row = DB[q].first BlackStack::Division.where(:id=>row[:id]).first end |
#get_balance ⇒ Object
232 233 234 235 236 237 238 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 232 def get_balance() n = 0 BlackStack::InvoicingPaymentsProcessing::products_descriptor.each { |code| n += BlackStack::Balance.new(self.id, code).amount } n end |
#get_movements(from_time, to_time, product_code = nil) ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 241 def get_movements(from_time, to_time, product_code=nil) if from_time > to_time raise "From time must be earlier than To time" end #if to_time.prev_year > from_time # raise "The time frame cannot be longer than 1 year." #end to_time += 1 =begin :id => movement.id, :id_client => movement.id_client, :product_code => movement.product_code, :create_time => movement.create_time, :type => movement.type.to_i, :description => movement.description, :paypal1_amount => movement.paypal1_amount.to_f, :bonus_amount => movement.bonus_amount.to_f, :amount => movement.amount.to_f, :credits => movement.credits.to_f, :profits_amount => movement.profits_amount.to_f, :expiration_time => movement.expiration_time, :expiration_description => movement.expiration_time.nil? ? '-' : ((movement.expiration_time - Time.now()).to_f / 60.to_f).to_i.to_time_spent =end q = "SELECT " + " m.id_client, " + " YEAR(m.create_time) AS creation_year, " + " MONTH(m.create_time) AS creation_month, " + " DAY(m.create_time) AS creation_day, " + " YEAR(m.expiration_time) AS expiration_year, " + " MONTH(m.expiration_time) AS expiration_month, " + " DAY(m.expiration_time) AS expiration_day, " + " m.type, " + " m.product_code, " + " CAST(m.description AS VARCHAR(500)) AS description, " + " CAST(m.expiration_description AS VARCHAR(500)) AS expiration_description, " + " SUM(ISNULL(m.paypal1_amount,0)) AS paypal1_amount, " + " SUM(ISNULL(m.bonus_amount,0)) AS bonus_amount, " + " SUM(ISNULL(m.amount,0)) AS amount, " + " SUM(ISNULL(m.credits,0)) AS credits, " + " SUM(ISNULL(m.profits_amount,0)) AS profits_amount " + "FROM movement m WITH (NOLOCK) " + "WHERE m.id_client = '#{self.id}' " q += "AND m.product_code = '#{product_code}' " if !product_code.nil? q += "AND create_time >= '#{from_time.to_sql}' " + "AND create_time <= '#{to_time.to_sql}' " + "GROUP BY " + " m.id_client, " + " YEAR(m.create_time), " + " MONTH(m.create_time), " + " DAY(m.create_time), " + " YEAR(m.expiration_time), " + " MONTH(m.expiration_time), " + " DAY(m.expiration_time), " + " m.type, " + " m.product_code, " + " CAST(m.description AS VARCHAR(500)), " + " CAST(m.expiration_description AS VARCHAR(500)) " DB[q].all end |
#has_item(item_number, amount = nil) ⇒ Object
retorna true si existe algun item de factura relacionado al ‘plan’ (‘item_number’). si el atributo ‘amount’ ademas es distinto a nil, se filtran items por ese monto.
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 338 def has_item(item_number, amount=nil) h = BlackStack::InvoicingPaymentsProcessing::plans_descriptor.select { |obj| obj[:item_number].to_s == item_number.to_s }.first raise "Plan not found" if h.nil? q = "SELECT i.id " + "FROM invoice i " # si el plan tiene un trial, entnces se pregunta si ya existe un item de factura por el importe del trial. # si el plan no tiene un trial, entnces se pregunta si ya existe un item de factura por el importe del plan. if amount.nil? q += "JOIN invoice_item t ON ( i.id=t.id_invoice AND t.item_number='#{item_number}' ) " else q += "JOIN invoice_item t ON ( i.id=t.id_invoice AND t.item_number='#{item_number}' AND t.amount=#{amount.to_s} ) " end q += "WHERE i.id_client='#{self.id}' " + "AND i.delete_time IS NULL " return !DB[q].first.nil? end |
#movements ⇒ Object
This method replace the line: one_to_many :movements, :class=>:‘BlackStack::Movement’, :key=>:id_client
Because when you have a large number of records in the table movement, for a client, then the call to this attribute client.movements can take too much time and generates a query timeout exception.
The call to this method may take too much time, but ti won’t raise a query timeout.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 19 def movements i = 0 ret = [] BlackStack::Movement.where(:id_client=>self.id).each { |o| ret << o i += 1 if i == 1000 i = 0 GC.start DB.disconnect end } ret end |
#plans ⇒ Object
retorna los planes estandar definidos en el array BlackStack::InvoicingPaymentsProcessing::plans_descriptor, y le concatena los arrays customizados de este cliente definidos en la tabla custom_plan
364 365 366 367 368 369 370 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 364 def plans a = BlackStack::InvoicingPaymentsProcessing::plans_descriptor self.customplans.each { |p| a << p.to_hash } a end |
#recalculate(product_code) ⇒ Object
recalculate the amount for all the consumptions, expirations, and adjustments
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 170 def recalculate(product_code) # amount_paid = 0.to_f credits_paid = 0 #total_credits = 0.to_f - BlackStack::Balance.new(self.id, product_code).credits.to_f #total_amount = 0.to_f - BlackStack::Balance.new(self.id, product_code).amount.to_f self.movements.select { |o| o.product_code.upcase == product_code.upcase }.sort_by { |o| [o.create_time, o.type] }.each { |o| # se ordena por o.create_time, pero tmabien por o.type para procesar primero los pagos y bonos #if o.credits.to_f < 0 # payment or bonus # if o.credits.to_f > 0 && ( o.type==BlackStack::Movement::MOVEMENT_TYPE_CANCELATION || o.type==BlackStack::Movement::MOVEMENT_TYPE_EXPIRATION ) # consumption or expiration # consumption or expiration or bonus if ( o.type==BlackStack::Movement::MOVEMENT_TYPE_CANCELATION || o.type==BlackStack::Movement::MOVEMENT_TYPE_EXPIRATION || o.type==BlackStack::Movement::MOVEMENT_TYPE_ADJUSTMENT ) x = credits_paid.to_f == 0 ? 0 : o.credits.to_f * ( amount_paid.to_f / credits_paid.to_f ) o.amount = x o.profits_amount = -x o.save end amount_paid += 0.to_f - o.amount.to_f credits_paid += 0.to_i - o.credits.to_i # if there is negative credits total_credits = credits_paid total_amount = amount_paid if total_credits < 0 self. adjustment(product_code, total_amount, total_credits, 'Adjustment Because Quota Has Been Exceeded (2).', BlackStack::Movement::MOVEMENT_TYPE_ADJUSTMENT, o.create_time) amount_paid = 0.to_f credits_paid = 0.to_i end } end |
#stat_balance_delay_minutes ⇒ Object
how many minutes ago should have updated the table stat_balance with the amount and credits of this client, for each product. return a positive integer if either:
-
the client didn’t update stats in the last 24 hours, or
-
the client has a new record in the table movements after its last update in the table stat_balance.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 38 def stat_balance_delay_minutes row = DB[ "SELECT TOP 1 m.id " + "FROM client c WITH (NOLOCK) " + "JOIN movement m WITH (NOLOCK INDEX(IX_movement__id_client__create_time_desc)) ON ( " + " c.id=m.id_client AND " + " m.create_time > ISNULL(c.last_stat_balance_update_time, '1900-01-01') " + ") " + "WHERE c.id = '#{self.id}' " + "ORDER BY m.create_time DESC " ].first if row.nil? return 0 else return DB["SELECT DATEDIFF(MI, m.create_time, GETDATE()) AS n FROM movement m WITH (NOLOCK) WHERE m.id='#{row[:id]}'"].first[:n] end end |
#update_stat_balance(product_code = nil) ⇒ Object
update the table stat_balance with the amount and credits of this client, for each product.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/extend_client_by_invoicing_payments_processing.rb', line 58 def update_stat_balance(product_code=nil) c = self product_descriptors = BlackStack::InvoicingPaymentsProcessing::products_descriptor.clone product_descriptors.select! { |hprod| hprod[:code] == product_code } if !product_code.nil? product_descriptors.each { |hprod| row1 = DB[" select isnull(sum(isnull(m.credits,0)),0) as credits from movement m with (nolock index(IX_movement__id_client__product_code)) --from movement m with (nolock) where m.id_client='#{c.id}' and m.product_code='#{hprod[:code]}' "].first row2 = DB[" select isnull(sum(isnull(m.amount,0)),0) as amount from movement m with (nolock index(IX_movement__id_client__product_code)) --from movement m with (nolock) where m.id_client='#{c.id}' and m.product_code='#{hprod[:code]}' "].first credits = row1[:credits] amount = row2[:amount] row = DB["SELECT * FROM stat_balance WHERE id_client='#{c.id}' AND product_code='#{hprod[:code]}'"].first if row.nil? DB.execute("INSERT INTO stat_balance (id_client, product_code, amount, credits) VALUES ('#{c.id}', '#{hprod[:code]}', #{amount.to_s}, #{credits.to_s})") else DB.execute("UPDATE stat_balance SET amount=#{amount.to_s}, credits=#{credits.to_s} WHERE id_client='#{c.id}' AND product_code='#{hprod[:code]}'") end DB.execute("UPDATE client SET last_stat_balance_update_time=GETDATE() WHERE [id]='#{c.id}'") } end |