Module: EffectiveCpdAudit

Extended by:
ActiveSupport::Concern
Defined in:
app/models/concerns/effective_cpd_audit.rb

Overview

EffectiveCpdAudit

Mark your owner model with effective_cpd_audit to get all the includes

Defined Under Namespace

Modules: Base, ClassMethods

Instance Method Summary collapse

Instance Method Details

#anonymous?Boolean

Returns:

  • (Boolean)


321
322
323
# File 'app/models/concerns/effective_cpd_audit.rb', line 321

def anonymous?
  cpd_audit_level&.anonymous?
end

#assign_anonymous_name_and_numberObject

The name pattern is A23XXX where XXX is an autoincrement The name pattern is A23XXX where XXX is an autoincrement



649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
# File 'app/models/concerns/effective_cpd_audit.rb', line 649

def assign_anonymous_name_and_number
  return if anonymous_name.present? || anonymous_number.present?
  return if cpd_audit_level.blank?

  prefix = cpd_audit_level.anonymous_audits_prefix
  raise('expected cpd audit level to have an anonymous prefix') unless prefix.present?

  # Where starts with prefix
  number = (self.class.all.where('anonymous_name LIKE ?', "#{prefix}%").maximum('anonymous_number') || 0) + 1 # The next number

  # Apply prefix and pad number to 3 digits
  name = prefix + number.to_s.rjust(3, '0')

  assign_attributes(anonymous_number: number, anonymous_name: name)
end

#chat_always?Boolean

Returns:

  • (Boolean)


349
350
351
# File 'app/models/concerns/effective_cpd_audit.rb', line 349

def chat_always?
  chat_permission == 'Always send messages'
end

#chat_never?Boolean

Returns:

  • (Boolean)


353
354
355
# File 'app/models/concerns/effective_cpd_audit.rb', line 353

def chat_never?
  chat_permission == 'Never send messages'
end

#chat_until_closed?Boolean

Returns:

  • (Boolean)


345
346
347
# File 'app/models/concerns/effective_cpd_audit.rb', line 345

def chat_until_closed?
  chat_permission == 'Can send messages until closed'
end

#close!Object

Admin action



600
601
602
603
# File 'app/models/concerns/effective_cpd_audit.rb', line 600

def close!
  closed!
  send_email(:cpd_audit_closed)
end

#complete!Object



549
550
551
552
553
554
555
556
557
558
559
560
561
# File 'app/models/concerns/effective_cpd_audit.rb', line 549

def complete!
  raise('audit must have been submitted to complete!') unless 

  existing = cpd_audit_reviews.select { |cpd_audit_review| cpd_audit_review.persisted? }

  assign_attributes(missing_info_reason: nil)
  completed!

  # Each of these sends a cpd_audit_review_ready email
  existing.each { |cpd_audit_review| cpd_audit_review.ready! }

  true
end

#completed_requirementsObject

When an audit is submitted, these must be done to go to completed. An Admin can override this and just set them to completed.



539
540
541
# File 'app/models/concerns/effective_cpd_audit.rb', line 539

def completed_requirements
  {}
end

#cpd_audit_level_section(wizard_step) ⇒ Object



407
408
409
410
# File 'app/models/concerns/effective_cpd_audit.rb', line 407

def cpd_audit_level_section(wizard_step)
  position = (wizard_step.to_s.split('section').last.to_i rescue false)
  cpd_audit_level.cpd_audit_level_sections.find { |section| (section.position + 1) == position }
end

#cpd_audit_response(cpd_audit_level_question) ⇒ Object

Find or build



413
414
415
416
# File 'app/models/concerns/effective_cpd_audit.rb', line 413

def cpd_audit_response(cpd_audit_level_question)
  cpd_audit_response = cpd_audit_responses.find { |r| r.cpd_audit_level_question_id == cpd_audit_level_question.id }
  cpd_audit_response ||= cpd_audit_responses.build(cpd_audit: self, cpd_audit_level_question: cpd_audit_level_question)
end

#deadline_dateObject



325
326
327
# File 'app/models/concerns/effective_cpd_audit.rb', line 325

def deadline_date
  (extension_date || notification_date)
end

#deadline_to_conflict_of_interestObject



614
615
616
617
618
619
620
# File 'app/models/concerns/effective_cpd_audit.rb', line 614

def deadline_to_conflict_of_interest
  return nil unless cpd_audit_level&.conflict_of_interest?
  return nil unless cpd_audit_level.days_to_declare_conflict.present?

  date = (notification_date || created_at || Time.zone.now)
  EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_declare_conflict)
end

#deadline_to_exemptionObject



622
623
624
625
626
627
628
# File 'app/models/concerns/effective_cpd_audit.rb', line 622

def deadline_to_exemption
  return nil unless cpd_audit_level&.can_request_exemption?
  return nil unless cpd_audit_level.days_to_request_exemption.present?

  date = (notification_date || created_at || Time.zone.now)
  EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_request_exemption)
end

#deadline_to_extensionObject



630
631
632
633
634
635
636
# File 'app/models/concerns/effective_cpd_audit.rb', line 630

def deadline_to_extension
  return nil unless cpd_audit_level&.can_request_extension?
  return nil unless cpd_audit_level.days_to_request_extension.present?

  date = (notification_date || created_at || Time.zone.now)
  EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_request_extension)
end

#deadline_to_submitObject



638
639
640
641
642
643
644
645
# File 'app/models/concerns/effective_cpd_audit.rb', line 638

def deadline_to_submit
  return extension_date if extension_date.present?

  return nil unless cpd_audit_level&.days_to_submit.present?

  date = (notification_date || created_at || Time.zone.now)
  EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_submit)
end

#deny_exemption!Object



464
465
466
467
468
# File 'app/models/concerns/effective_cpd_audit.rb', line 464

def deny_exemption!
  assign_attributes(exemption_request: false)
  exemption_denied!
  send_email(:cpd_audit_exemption_denied)
end

#deny_extension!Object



497
498
499
500
501
# File 'app/models/concerns/effective_cpd_audit.rb', line 497

def deny_extension!
  assign_attributes(extension_request: false)
  extension_denied!
  send_email(:cpd_audit_extension_denied)
end

#done?Boolean

Returns:

  • (Boolean)


337
338
339
# File 'app/models/concerns/effective_cpd_audit.rb', line 337

def done?
  self.class.done_states.include?(status.to_sym)
end

#draft?Boolean

Returns:

  • (Boolean)


329
330
331
# File 'app/models/concerns/effective_cpd_audit.rb', line 329

def draft?
  ! && !closed?
end

#email_form_defaults(action) ⇒ Object



605
606
607
# File 'app/models/concerns/effective_cpd_audit.rb', line 605

def email_form_defaults(action)
  { from: EffectiveCpd.mailer_sender }
end

#exemption!Object

Auditee wizard action



441
442
443
444
445
446
# File 'app/models/concerns/effective_cpd_audit.rb', line 441

def exemption!
  return started! unless exemption_request?

  update!(status: :exemption_requested)
  send_email(:cpd_audit_exemption_request)
end

#extension!Object

Auditee wizard action



471
472
473
474
475
476
# File 'app/models/concerns/effective_cpd_audit.rb', line 471

def extension!
  return started! unless extension_request?

  update!(status: :extension_requested)
  send_email(:cpd_audit_extension_request)
end

#feedbackObject



669
670
671
# File 'app/models/concerns/effective_cpd_audit.rb', line 669

def feedback
  (cpd_audit_reviews.map(&:feedback) - [nil, '', ' ']).join("\n")
end

#grant_exemption!Object



458
459
460
461
462
# File 'app/models/concerns/effective_cpd_audit.rb', line 458

def grant_exemption!
  wizard_steps[:submit] ||= Time.zone.now
   && exemption_granted!
  send_email(:cpd_audit_exemption_granted)
end

#grant_extension!Object



488
489
490
491
492
493
494
495
# File 'app/models/concerns/effective_cpd_audit.rb', line 488

def grant_extension!
  self.extension_date = extension_request_date
  self.due_date = deadline_to_submit()

  cpd_audit_reviews.each { |cpd_audit_review| cpd_audit_review.extension_granted! }
  extension_granted!
  send_email(:cpd_audit_extension_granted)
end

#in_progress?Boolean

Returns:

  • (Boolean)


333
334
335
# File 'app/models/concerns/effective_cpd_audit.rb', line 333

def in_progress?
  self.class.done_states.include?(status.to_sym) == false
end

#missing!Object



563
564
565
566
567
568
# File 'app/models/concerns/effective_cpd_audit.rb', line 563

def missing!
  raise('audit must have been submitted to missing!') unless 

  missing_info!
  send_email(:cpd_audit_missing_info)
end

#nameObject



317
318
319
# File 'app/models/concerns/effective_cpd_audit.rb', line 317

def name
  anonymous_name.presence || user.to_s
end

#notify!Object



418
419
420
421
# File 'app/models/concerns/effective_cpd_audit.rb', line 418

def notify!
  send_email(:cpd_audit_opened)
  true
end

#process_exemption!Object

Admin action



449
450
451
452
453
454
455
456
# File 'app/models/concerns/effective_cpd_audit.rb', line 449

def process_exemption!
  case admin_process_request
  when 'Granted' then grant_exemption!
  when 'Denied' then deny_exemption!
  else
    self.errors.add(:admin_process_request, "can't be blank"); save!
  end
end

#process_extension!Object

Admin action



479
480
481
482
483
484
485
486
# File 'app/models/concerns/effective_cpd_audit.rb', line 479

def process_extension!
  case admin_process_request
  when 'Granted' then grant_extension!
  when 'Denied' then deny_extension!
  else
    self.errors.add(:admin_process_request, "can't be blank"); save!
  end
end

#ready_to_review?Boolean

Returns:

  • (Boolean)


341
342
343
# File 'app/models/concerns/effective_cpd_audit.rb', line 341

def ready_to_review?
  was_completed?
end

#required_cpd_cycleObject



514
515
516
517
518
519
# File 'app/models/concerns/effective_cpd_audit.rb', line 514

def required_cpd_cycle
  @required_cpd_cycle ||= begin
    last_year = ((notification_date || created_at || Time.zone.now) - 1.year).all_year
    Effective::CpdCycle.available.where(start_at: last_year).first
  end
end

#resolve_conflict!Object

Admin action



429
430
431
432
433
434
435
436
437
438
# File 'app/models/concerns/effective_cpd_audit.rb', line 429

def resolve_conflict!
  wizard_steps[:conflict] = nil   # Have them complete the conflict step again.

  assign_attributes(conflict_of_interest: false, conflict_of_interest_reason: nil)
  conflicted_resolved!
  

  send_email(:cpd_audit_conflict_resolved)
  true
end

#resubmit!Object



570
571
572
573
574
575
576
577
578
# File 'app/models/concerns/effective_cpd_audit.rb', line 570

def resubmit!
  raise('audit must have been submitted and missing info to resubmit!') unless  && was_missing_info?
  raise('already submitted') if 

  assign_attributes(skip_to_step: :submitted, submitted_at: Time.zone.now)

  
  send_email(:cpd_audit_submitted)
end

#review!Object

Called in a before_save. Intended for applicant_review to call in its submit! method



590
591
592
593
594
595
596
597
# File 'app/models/concerns/effective_cpd_audit.rb', line 590

def review!
  raise('already reviewed') if was_reviewed?
  raise('audit must have been submitted to review!') unless 
  raise('audit must have been completed to review!') unless was_completed?

  reviewed!
  send_email(:cpd_audit_reviewed)
end

#send_email(email) ⇒ Object



609
610
611
612
# File 'app/models/concerns/effective_cpd_audit.rb', line 609

def send_email(email)
  EffectiveCpd.send_email(email, self, email_form_params) unless email_form_skip?
  true
end

#start!Object

Auditee wizard action



424
425
426
# File 'app/models/concerns/effective_cpd_audit.rb', line 424

def start!
  started!
end

#status_labelObject



357
358
359
# File 'app/models/concerns/effective_cpd_audit.rb', line 357

def status_label
  (status_was || status).to_s.gsub('_', ' ')
end

#submit!Object

Auditee wizard action



522
523
524
525
526
527
528
529
530
531
532
533
534
535
# File 'app/models/concerns/effective_cpd_audit.rb', line 522

def submit!
  # Complete the very last step too
  wizard_steps[:submitted] = Time.zone.now

  if conflict_of_interest?
    conflicted!
    send_email(:cpd_audit_conflicted)
  else
    
    send_email(:cpd_audit_submitted)
  end

  true
end

#suggested_cpd_audit_reviewersObject



665
666
667
# File 'app/models/concerns/effective_cpd_audit.rb', line 665

def suggested_cpd_audit_reviewers
  (current_user || user).class.send(EffectiveCpd.audit_reviewer_user_scope).sorted_by_in_progress_cpd_audit_reviews
end

#summaryObject



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'app/models/concerns/effective_cpd_audit.rb', line 361

def summary
  audit = model_name.human
  auditee = EffectiveCpd.CpdAudit.human_attribute_name(:user)
  reviewer = EffectiveCpd.CpdAuditReview.human_attribute_name(:user)
  reviewers = EffectiveCpd.CpdAuditReview.human_attribute_name(:user).pluralize

  case status_was
  when 'opened'
    "The #{audit} has been opened. The #{auditee} and #{reviewers} have been notified. Waiting for the #{auditee} to submit."
  when 'started'
    "The #{auditee} has started their #{audit}. Waiting for the #{auditee} to submit."
  when 'conflicted'
    "The #{auditee} has declared a conflict of interest. A new #{reviewer} will be assigned."
  when 'conflicted_resolved'
    "The #{auditee} had declared a conflict of interest. This has been resolved. Waiting for the #{auditee} to submit."
  when 'exemption_requested'
    "The #{auditee} has requested an exemption. Waiting for request to be granted or denied."
  when 'exemption_granted'
    "The exemption request has been granted. This #{audit} may now be closed."
  when 'exemption_denied'
    "The exemption request has been denied. The #{audit} will continue. Waiting for the #{auditee} to submit."
  when 'extension_requested'
    "The #{auditee} has requested an extension. Waiting for request to be granted or denied."
  when 'extension_granted'
    "The extension request has been granted. There is a new deadline. Waiting for the #{auditee} to submit."
  when 'extension_denied'
    "The extension request has been denied. The deadline remains. Waiting for the #{auditee} to submit."
  when 'submitted'
    summary = "#{auditee} has submitted their #{audit} wizard."
    tasks = "The following tasks remain before it can be completed:"
    approval = "Waiting on completeness check, review and determination."
    items = completed_requirements.map { |item, done| "<li>#{item}: #{done ? 'Complete' : 'Incomplete'}</li>" }.join
    completed_requirements.present? ? "<p>#{summary} #{tasks}</p><ul>#{items}</ul>" : "#{summary} #{approval}"
  when 'completed'
    "All required materials have been provided. Ready to review. This #{audit} will transition to 'reviewed' after all #{reviewers} have submitted."
  when 'missing_info'
    "Missing the following information: <ul><li>#{missing_info_reason}</li></ul>"
  when 'reviewed'
    "The #{audit} has been reviewed and is ready for the final determination to be made."
  when 'closed'
    "This #{audit} has been closed with a final determination #{determination}. All done."
  else
    raise("unexpected status #{status}")
  end.html_safe
end

#to_sObject



313
314
315
# File 'app/models/concerns/effective_cpd_audit.rb', line 313

def to_s
  (cpd_audit_level.present? && name.present?) ? "#{cpd_audit_level} #{model_name.human} of #{name}" : model_name.human
end

#try_complete!Object

called by a before_save when submitted



544
545
546
547
# File 'app/models/concerns/effective_cpd_audit.rb', line 544

def try_complete!
  # complete! if submitted? # Automatically go from submitted->complete
  false # Nothing to do. Admin completes audits.
end

#try_review!Object



580
581
582
583
584
585
586
587
# File 'app/models/concerns/effective_cpd_audit.rb', line 580

def try_review!
  return false unless 
  return false unless completed?
  return false unless cpd_audit_reviews.present? && cpd_audit_reviews.all?(&:completed?)
  return false if was_missing_info?

  review!
end

#user_cpd_completed?Boolean

Returns:

  • (Boolean)


509
510
511
512
# File 'app/models/concerns/effective_cpd_audit.rb', line 509

def user_cpd_completed?
  return true if required_cpd_cycle.blank?
  user.cpd_statements.any? { |s| s.completed? && s.cpd_cycle_id == required_cpd_cycle.id }
end

#user_cpd_required?Boolean

Require CPD step

Returns:

  • (Boolean)


504
505
506
507
# File 'app/models/concerns/effective_cpd_audit.rb', line 504

def user_cpd_required?
  return false unless user.cpd_audit_cpd_required?
  required_cpd_cycle.present?
end