Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/blueprints/agreements/iaa_blueprint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Agreements
class IaaBlueprint < Blueprinter::Base
identifier :iaa_number

field :partner_account
field :gtc_number
field :gtc_mod_number
field :gtc_start_date, datetime_format: '%Y-%m-%d'
field :gtc_end_date, datetime_format: '%Y-%m-%d'
field :gtc_estimated_amount
field :gtc_status
field :order_number
field :order_mod_number
field :order_start_date, datetime_format: '%Y-%m-%d'
field :order_end_date, datetime_format: '%Y-%m-%d'
field :order_estimated_amount
field :order_status
end
end
33 changes: 33 additions & 0 deletions app/models/agreements/iaa.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Abstract class to combine IaaGtcs and IaaOrders for JSON serialization
module Agreements
class Iaa
include ActiveModel::Model

attr_accessor :gtc, :order

delegate :gtc_number, to: :gtc
delegate :order_number, to: :order
delegate :mod_number, :start_date, :end_date, :estimated_amount, to: :gtc, prefix: true
delegate :mod_number, :start_date, :end_date, :estimated_amount, to: :order, prefix: true

def iaa_number
"#{gtc.gtc_number}-#{'%04d' % order.order_number}-#{'%04d' % order.mod_number}"
end

def partner_account
gtc.partner_account.requesting_agency
end

def gtc_status
gtc.partner_status
end

def order_status
order.partner_status
end

def ==(other)
other.gtc == gtc && other.order == order
end
end
end
4 changes: 4 additions & 0 deletions app/models/agreements/iaa_gtc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ class Agreements::IaaGtc < ApplicationRecord
validates :estimated_amount, numericality: { less_than: 10_000_000_000,
greater_than_or_equal_to: 0,
allow_nil: true }

def partner_status
iaa_status.partner_name
end
end
4 changes: 4 additions & 0 deletions app/models/agreements/iaa_order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ class Agreements::IaaOrder < ApplicationRecord
validates :estimated_amount, numericality: { less_than: 10_000_000_000,
greater_than_or_equal_to: 0,
allow_nil: true }

def partner_status
iaa_status.partner_name
end
end
4 changes: 4 additions & 0 deletions app/models/agreements/iaa_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ class Agreements::IaaStatus < ApplicationRecord
validates :order, presence: true,
uniqueness: true,
numericality: { only_integer: true }

def partner_name
super || name
end
end
18 changes: 18 additions & 0 deletions app/services/agreements/db/iaas_by_agency.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Agreements
module Db
class IaasByAgency
def self.call
IaaGtc.
includes(:iaa_status, partner_account: :agency, iaa_orders: :iaa_status).
group_by { |gtc| gtc.partner_account.agency.abbreviation }.
transform_values do |gtcs|
gtcs.map do |gtc|
gtc.iaa_orders.map do |order|
Iaa.new(gtc: gtc, order: order)
end
end.flatten
end
end
end
end
end
24 changes: 24 additions & 0 deletions app/services/agreements/reports/agency_iaas_report.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Agreements
module Reports
class AgencyIaasReport < BaseReport
def initialize(agency:, iaas:)
@agency = agency
@iaas = iaas.sort_by do |iaa|
[iaa.partner_account, iaa.iaa_number]
end
end

def run
save_report(
'agreements',
IaaBlueprint.render(iaas, root: :agreements),
"agencies/#{agency}/",
)
end

private

attr_reader :agency, :iaas
end
end
end
14 changes: 13 additions & 1 deletion app/services/agreements/reports/partner_api_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,28 @@ def run
return unless IdentityConfig.store.enable_partner_api

collect_account_data
collect_iaa_data
upload_json_files
true
end

private

attr_reader :accounts_by_agency, :agencies
attr_reader :accounts_by_agency, :agencies, :iaas_by_agency

def collect_account_data
@accounts_by_agency = Agreements::Db::AccountsByAgency.call
@agencies = accounts_by_agency.keys
@accounts_by_agency = accounts_by_agency.transform_keys(&:abbreviation)
end

def collect_iaa_data
@iaas_by_agency = Agreements::Db::IaasByAgency.call
end

def upload_json_files
upload_agencies
upload_iaas
upload_accounts
end

Expand All @@ -33,6 +39,12 @@ def upload_accounts
AgencyPartnerAccountsReport.new(agency: agency_abbr, partner_accounts: accounts).run
end
end

def upload_iaas
iaas_by_agency.each do |agency_abbr, iaas|
AgencyIaasReport.new(agency: agency_abbr, iaas: iaas).run
end
end
end
end
end
62 changes: 62 additions & 0 deletions spec/blueprints/agreements/iaa_blueprint_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
require 'rails_helper'

RSpec.describe Agreements::IaaBlueprint do
let(:account) { create(:partner_account, requesting_agency: 'ABC-DEF') }
let(:status) { create(:iaa_status, name: 'private name', partner_name: 'active') }
let(:gtc) do
create(
:iaa_gtc,
partner_account: account,
gtc_number: 'LGABC210001',
mod_number: 0,
start_date: '2021-01-01',
end_date: '2025-12-31',
estimated_amount: 100_000,
iaa_status: status,
)
end
let(:order) do
create(
:iaa_order,
iaa_gtc: gtc,
order_number: 1,
mod_number: 0,
start_date: '2021-01-01',
end_date: '2021-12-31',
estimated_amount: 20_000.53,
iaa_status: status,
)
end
let(:iaa) do
Agreements::Iaa.new(
gtc: gtc,
order: order,
)
end
let(:expected) do
{
agreements: [
{
iaa_number: 'LGABC210001-0001-0000',
partner_account: 'ABC-DEF',
gtc_number: 'LGABC210001',
gtc_mod_number: 0,
gtc_start_date: '2021-01-01',
gtc_end_date: '2025-12-31',
gtc_estimated_amount: '100000.0',
gtc_status: 'active',
order_number: 1,
order_mod_number: 0,
order_start_date: '2021-01-01',
order_end_date: '2021-12-31',
order_estimated_amount: '20000.53',
order_status: 'active',
},
],
}.to_json
end

it 'renders the appropriate json' do
expect(described_class.render([iaa], root: :agreements)).to eq(expected)
end
end
9 changes: 9 additions & 0 deletions spec/models/agreements/iaa_gtc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,13 @@

it { is_expected.to have_many(:iaa_orders).dependent(:restrict_with_exception) }
end

describe '#partner_status' do
it 'returns the partner_name of the associated iaa_status' do
status = build(:iaa_status, partner_name: 'foo')
gtc = build(:iaa_gtc, iaa_status: status)

expect(gtc.partner_status).to eq('foo')
end
end
end
9 changes: 9 additions & 0 deletions spec/models/agreements/iaa_order_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,13 @@
it { is_expected.to have_many(:integration_usages).dependent(:restrict_with_exception) }
it { is_expected.to have_many(:integrations).through(:integration_usages) }
end

describe '#partner_status' do
it 'returns the partner_name of the associated iaa_status' do
status = build(:iaa_status, partner_name: 'foo')
order = build(:iaa_order, iaa_status: status)

expect(order.partner_status).to eq('foo')
end
end
end
62 changes: 62 additions & 0 deletions spec/models/agreements/iaa_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
require 'rails_helper'

RSpec.describe Agreements::Iaa do
let(:gtc) { create(:iaa_gtc, gtc_number: 'LGABC210001') }
let(:order) { create(:iaa_order, iaa_gtc: gtc, order_number: 1, mod_number: 2) }
let(:iaa) { described_class.new(gtc: gtc, order: order) }

it { is_expected.to delegate_method(:gtc_number).to(:gtc) }
it { is_expected.to delegate_method(:mod_number).to(:gtc).with_prefix }
it { is_expected.to delegate_method(:start_date).to(:gtc).with_prefix }
it { is_expected.to delegate_method(:end_date).to(:gtc).with_prefix }
it { is_expected.to delegate_method(:estimated_amount).to(:gtc).with_prefix }
it { is_expected.to delegate_method(:order_number).to(:order) }
it { is_expected.to delegate_method(:mod_number).to(:order).with_prefix }
it { is_expected.to delegate_method(:start_date).to(:order).with_prefix }
it { is_expected.to delegate_method(:end_date).to(:order).with_prefix }
it { is_expected.to delegate_method(:estimated_amount).to(:order).with_prefix }

describe '#iaa_number' do
it 'returns the formatted IAA number' do
expect(iaa.iaa_number).to eq('LGABC210001-0001-0002')
end
end

describe '#partner_account' do
it 'returns the requesting agency of the partner account' do
expect(iaa.partner_account).to eq(gtc.partner_account.requesting_agency)
end
end

describe '#gtc_status' do
it 'returns the partner-facing status of the GTC' do
expect(iaa.gtc_status).to eq(gtc.partner_status)
end
end

describe '#order_status' do
it 'returns the partner-facing status of the order' do
expect(iaa.order_status).to eq(order.partner_status)
end
end

describe 'delegated methods' do
it 'does not permit arbitrary sends to the gtc or order objects' do
expect{ iaa.send('gtc_not_permitted') }.to raise_error(NoMethodError)
expect{ iaa.send('order_not_permitted') }.to raise_error(NoMethodError)
end
end

describe '#==' do
it 'returns true when both the order and the gtc are equal' do
other = described_class.new(gtc: gtc, order: order)
expect(iaa).to eq(other)
end

it 'returns false when the order does not match' do
other_order = create(:iaa_order, iaa_gtc: gtc)
other = described_class.new(gtc: gtc, order: other_order)
expect(iaa).not_to eq(other)
end
end
end
12 changes: 12 additions & 0 deletions spec/models/agreements/iaa_status_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,16 @@
it { is_expected.to have_many(:iaa_gtcs).dependent(:restrict_with_exception) }
it { is_expected.to have_many(:iaa_orders).dependent(:restrict_with_exception) }
end

describe '#partner_name' do
it 'returns the partner_name if set' do
status = build(:iaa_status, name: 'foo', partner_name: 'bar')
expect(status.partner_name).to eq('bar')
end

it 'returns the name if no partner_name is set' do
status = build(:iaa_status, name: 'foo', partner_name: nil)
expect(status.partner_name).to eq('foo')
end
end
end
35 changes: 35 additions & 0 deletions spec/services/agreements/db/iaas_by_agency_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'rails_helper'

RSpec.describe Agreements::Db::IaasByAgency do
let(:agency) { create(:agency) }
let(:partner_account1) { create(:partner_account, agency: agency, requesting_agency: 'DEF') }
let(:partner_account2) { create(:partner_account, agency: agency, requesting_agency: 'ABC') }
let(:gtc1) { create(:iaa_gtc, partner_account: partner_account1, gtc_number: 'LGAADEF210001') }
let(:gtc2) { create(:iaa_gtc, partner_account: partner_account2, gtc_number: 'LGABC210001') }
let(:gtc1order1) { create(:iaa_order, iaa_gtc: gtc1, order_number: 1) }
let(:gtc1order2) { create(:iaa_order, iaa_gtc: gtc1, order_number: 2) }
let(:gtc2order1) { create(:iaa_order, iaa_gtc: gtc2, order_number: 1) }
let(:iaas) do
[
# this is unfortunately order-dependent
Agreements::Iaa.new(gtc: gtc1, order: gtc1order1),
Agreements::Iaa.new(gtc: gtc1, order: gtc1order2),
Agreements::Iaa.new(gtc: gtc2, order: gtc2order1),
]
end
let(:other_agency_order) { create(:iaa_order) }
let(:other_agency_gtc) { other_agency_order.iaa_gtc }
let(:other_agency) { other_agency_gtc.partner_account.agency }

before { clear_agreements_data }

it 'returns all agreements encapsulated in an Iaa model grouped by agency' do
expected = {
agency.abbreviation => iaas,
other_agency.abbreviation => [
Agreements::Iaa.new(gtc: other_agency_gtc, order: other_agency_order),
],
}
expect(described_class.call).to eq(expected)
end
end
Loading