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)


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

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



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

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)


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

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

#chat_never?Boolean

Returns:

  • (Boolean)


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

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

#chat_until_closed?Boolean

Returns:

  • (Boolean)


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

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



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

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.



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

def completed_requirements
  {}
end

#cpd_audit_level_section(wizard_step) ⇒ Object



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

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



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

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



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

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
# File 'app/models/concerns/effective_cpd_audit.rb', line 638

def deadline_to_submit
  return nil unless cpd_audit_level&.days_to_submit.present?

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

#deny_exemption!Object



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

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

#deny_extension!Object



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

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

#done?Boolean

Returns:

  • (Boolean)


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

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

#draft?Boolean

Returns:

  • (Boolean)


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

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



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

def exemption!
  return started! unless exemption_request?

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

#extension!Object

Auditee wizard action



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

def extension!
  return started! unless extension_request?

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

#grant_exemption!Object



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

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

#grant_extension!Object



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

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)


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

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

#missing!Object



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

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

  missing_info!
  send_email(:cpd_audit_missing_info)
end

#nameObject



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

def name
  anonymous_name.presence || user.to_s
end

#notify!Object



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

def notify!
  send_email(:cpd_audit_opened)
  true
end

#process_exemption!Object

Admin action



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

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



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

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)


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

def ready_to_review?
  was_completed?
end

#required_cpd_cycleObject



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

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



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

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



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

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



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

def start!
  started!
end

#status_labelObject



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

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

#submit!Object

Auditee wizard action



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

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



663
664
665
# File 'app/models/concerns/effective_cpd_audit.rb', line 663

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

#summaryObject



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
406
# File 'app/models/concerns/effective_cpd_audit.rb', line 362

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



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

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



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

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

#try_review!Object



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

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

  review!
end

#user_cpd_completed?Boolean

Returns:

  • (Boolean)


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

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)


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

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