Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Hidden goods nomenclatures #38

Merged
merged 8 commits into from

2 participants

@saulius

HiddenGoodsNomenclature allows us to specify which goods nomenclature codes should be hidden. For now I added everything in Chapter 99.

@matthewford matthewford merged commit cfd0054 into master
@matthewford

not that this actually makes much difference but this looks like a duplicate

Ah sorry, should have been distinct codes. 9905000000 has two producline suffixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
15 app/controllers/api/v1/chapters_controller.rb
@@ -3,11 +3,8 @@
module Api
module V1
class ChaptersController < ApplicationController
+ before_filter :find_chapter, only: [:show]
def show
- @chapter = Chapter.actual
- .where(goods_nomenclature_item_id: chapter_id)
- .take
-
@headings = GoodsNomenclatureMapper.new(@chapter.headings_dataset
.eager(:goods_nomenclature_description,
:goods_nomenclature_indent)
@@ -16,6 +13,16 @@ def show
respond_with @chapter
end
+ private
+
+ def find_chapter
+ @chapter = Chapter.actual
+ .where(goods_nomenclature_item_id: chapter_id)
+ .take
+
+ raise Sequel::RecordNotFound if @chapter.goods_nomenclature_item_id.in? HiddenGoodsNomenclature.codes
+ end
+
def chapter_id
"#{params[:id]}00000000"
end
View
17 app/controllers/api/v1/commodities_controller.rb
@@ -1,13 +1,9 @@
module Api
module V1
class CommoditiesController < ApplicationController
+ before_filter :find_commodity, only: [:show]
def show
- @commodity = Commodity.actual
- .declarable
- .by_code(params[:id])
- .take
-
@measures = MeasurePresenter.new(@commodity.measures_dataset.eager({geographical_area: [:geographical_area_description, :children_geographical_areas]},
{footnotes: :footnote_description},
{type: :measure_type_description},
@@ -31,6 +27,17 @@ def show
respond_with @commodity
end
+
+ private
+
+ def find_commodity
+ @commodity = Commodity.actual
+ .declarable
+ .by_code(params[:id])
+ .take
+
+ raise Sequel::RecordNotFound if @commodity.goods_nomenclature_item_id.in? HiddenGoodsNomenclature.codes
+ end
end
end
end
View
21 app/controllers/api/v1/headings_controller.rb
@@ -3,12 +3,9 @@
module Api
module V1
class HeadingsController < ApplicationController
- def show
- @heading = Heading.actual
- .non_grouping
- .where(goods_nomenclatures__goods_nomenclature_item_id: heading_id)
- .take
+ before_filter :find_heading, only: [:show]
+ def show
if @heading.declarable?
@measures = MeasurePresenter.new(@heading.measures_dataset.eager({geographical_area: [:geographical_area_description, :children_geographical_areas]},
{footnotes: :footnote_description},
@@ -32,13 +29,25 @@ def show
:measure_partial_temporary_stop).all, @heading).validate!
else
@commodities = GoodsNomenclatureMapper.new(@heading.commodities_dataset.eager(:goods_nomenclature_indent,
- :goods_nomenclature_description).all).all
+ :goods_nomenclature_description)
+ .all).all
end
respond_with @heading
end
+ private
+
+ def find_heading
+ @heading = Heading.actual
+ .non_grouping
+ .where(goods_nomenclatures__goods_nomenclature_item_id: heading_id)
+ .take
+
+ raise Sequel::RecordNotFound if @heading.goods_nomenclature_item_id.in? HiddenGoodsNomenclature.codes
+ end
+
def heading_id
"#{params[:id]}000000"
end
View
1  app/models/chapter.rb
@@ -15,6 +15,7 @@ class Chapter < GoodsNomenclature
one_to_many :headings, dataset: -> {
actual(Heading).filter("goods_nomenclature_item_id LIKE ? AND goods_nomenclature_item_id NOT LIKE '__00______'", relevant_headings)
+ .where(~{goods_nomenclatures__goods_nomenclature_item_id: HiddenGoodsNomenclature.codes })
}
one_to_one :chapter_note, dataset: -> {
View
9 app/models/goods_nomenclature.rb
@@ -122,9 +122,13 @@ class GoodsNomenclature < Sequel::Model
foreign_key: :goods_nomenclature_sid
dataset_module do
- def declarable
+ def declarable
filter(producline_suffix: 80)
end
+
+ def non_hidden
+ filter(~{goods_nomenclature_item_id: HiddenGoodsNomenclature.codes})
+ end
end
# TODO
@@ -156,3 +160,6 @@ def bti_url
end
end
+require 'heading'
+require 'chapter'
+require 'commodity'
View
1  app/models/heading.rb
@@ -14,6 +14,7 @@ class Heading < GoodsNomenclature
one_to_many :commodities, dataset: -> {
actual(Commodity).filter("goods_nomenclatures.goods_nomenclature_item_id LIKE ?", heading_id)
+ .where(~{goods_nomenclatures__goods_nomenclature_item_id: HiddenGoodsNomenclature.codes })
}
one_to_one :chapter, dataset: -> {
View
13 app/models/hidden_goods_nomenclature.rb
@@ -0,0 +1,13 @@
+class HiddenGoodsNomenclature < Sequel::Model
+ plugin :timestamps
+
+ set_dataset order(:goods_nomenclature_item_id.asc)
+
+ validates do
+ presence_of :goods_nomenclature_item_id
+ end
+
+ def self.codes
+ all.map(&:goods_nomenclature_item_id)
+ end
+end
View
2  app/models/section.rb
@@ -7,6 +7,7 @@ class Section < Sequel::Model
Chapter.join_table(:inner, :chapters_sections, chapters_sections__goods_nomenclature_sid: :goods_nomenclatures__goods_nomenclature_sid)
.join_table(:inner, :sections, chapters_sections__section_id: :sections__id)
.with_actual(Chapter)
+ .where(~{goods_nomenclatures__goods_nomenclature_item_id: HiddenGoodsNomenclature.codes })
.where(sections__id: id)
}, eager_loader: (proc do |eo|
eo[:rows].each{|section| section.associations[:chapters] = []}
@@ -17,6 +18,7 @@ class Section < Sequel::Model
.join_table(:inner, :sections, chapters_sections__section_id: :sections__id)
.eager(:goods_nomenclature_description)
.with_actual(Chapter)
+ .where(~{goods_nomenclatures__goods_nomenclature_item_id: HiddenGoodsNomenclature.codes })
.where(sections__id: id_map.keys).all do |chapter|
if sections = id_map[chapter[:section_id]]
sections.each do |section|
View
61 app/services/search_service.rb
@@ -25,22 +25,57 @@ def present?
class ExactSearch < BaseSearch
def search!
@results = case query_string
- when /^[0-9]{1,3}$/
- Chapter.actual.by_code(query_string).first
- when /^[0-9]{4,9}$/
- Heading.actual.by_code(query_string).first
- when /^[0-9]{10}$/
- Commodity.actual.by_code(query_string).declarable.first.presence ||
- Heading.actual.by_declarable_code(query_string).declarable.first.presence
- when /^\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}$/
- Commodity.actual.by_code(query_string.gsub(/\s+/, '')).declarable.first.presence ||
- Heading.actual.by_declarable_code(query_string.gsub(/\s+/, '')).declarable.first.presence
- when /^[0-9]{11,12}$/
- Commodity.actual.by_code(query_string).declarable.first
- end
+ when /^[0-9]{1,3}$/
+ Chapter.actual
+ .by_code(query_string)
+ .non_hidden
+ .first
+ when /^[0-9]{4,9}$/
+ Heading.actual
+ .by_code(query_string)
+ .non_hidden
+ .first
+ when /^[0-9]{10}$/
+ Commodity.actual
+ .by_code(query_string)
+ .non_hidden
+ .declarable
+ .first
+ .presence ||
+ Heading.actual
+ .by_declarable_code(query_string)
+ .declarable
+ .non_hidden
+ .first
+ .presence
+ when /^\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}$/
+ Commodity.actual
+ .by_code(query_string.gsub(/\s+/, ''))
+ .declarable
+ .non_hidden
+ .first
+ .presence ||
+ Heading.actual
+ .by_declarable_code(query_string.gsub(/\s+/, ''))
+ .declarable
+ .non_hidden
+ .first
+ .presence
+ when /^[0-9]{11,12}$/
+ Commodity.actual
+ .by_code(query_string)
+ .non_hidden
+ .declarable
+ .first
+ end
+
self
end
+ def present?
+ !query_string.in?(HiddenGoodsNomenclature.codes) && @results.present?
+ end
+
def serializable_hash
{
type: "exact_match",
View
9 db/migrate/20121204130816_create_hidden_goods_nomenclatures.rb
@@ -0,0 +1,9 @@
+Sequel.migration do
+ change do
+ create_table :hidden_goods_nomenclatures do
+ String :goods_nomenclature_item_id
+ DateTime :updated_at
+ DateTime :created_at
+ end
+ end
+end
View
29 db/migrate/20121204143748_add_hidden_commodities.rb
@@ -0,0 +1,29 @@
+Sequel.migration do
+ CODES =
+ ["9900000000",
+ "9905000000",
+ "9905000000",
+ "9919000000",
+ "9930000000",
+ "9930240000",
+ "9930270000",
+ "9930990000",
+ "9931000000",
+ "9931240000",
+ "9931270000",
+ "9931990000",
+ "9950000000"]
+
+ up do
+ CODES.each do |code|
+ HiddenGoodsNomenclature.create(goods_nomenclature_item_id: code)
+ end
+ end
+
+ down do
+ CODES.each do |code|
+ HiddenGoodsNomenclature.where(goods_nomenclature_item_id: code)
+ .delete
+ end
+ end
+end
View
8 db/schema.rb
@@ -808,6 +808,12 @@
index [:goods_nomenclature_sid], :name=>:primary_key, :unique=>true
end
+ create_table(:hidden_goods_nomenclatures) do
+ column :goods_nomenclature_item_id, "varchar(255)"
+ column :updated_at, "datetime"
+ column :created_at, "datetime"
+ end
+
create_table(:language_descriptions) do
column :language_code_id, "varchar(255)"
column :language_id, "varchar(5)"
@@ -1547,6 +1553,8 @@
self[:schema_migrations].insert(:filename => "20121109121107_fix_chief_last_effective_dates.rb")
self[:schema_migrations].insert(:filename => "20121109121219_remove_invalid_measures.rb")
self[:schema_migrations].insert(:filename => "20121129094209_add_invalidated_columns_to_measures.rb")
+ self[:schema_migrations].insert(:filename => "20121204130816_create_hidden_goods_nomenclatures.rb")
+ self[:schema_migrations].insert(:filename => "20121204143748_add_hidden_commodities.rb")
create_table(:search_references) do
primary_key :id, :type=>"int(11)"
View
7 lib/tasks/tariff.rake
@@ -19,6 +19,13 @@ namespace :tariff do
ENV['CLASS'] = klass
Rake::Task['tire:import'].execute
end
+
+ # Remove hidden goods nomenclatures
+ # TODO: is there a better solution?
+
+ GoodsNomenclature.where(goods_nomenclature_item_id: HiddenGoodsNomenclature.codes).all.each do |gono|
+ gono.class.tire.index.remove gono
+ end
end
desc 'Download and apply Taric and CHIEF data'
View
8 spec/controllers/api/v1/chapters_controller_spec.rb
@@ -27,4 +27,12 @@
expect { get :show, id: "55", format: :json }.to raise_error Sequel::RecordNotFound
end
end
+
+ context 'when record is hidden' do
+ let!(:hidden_goods_nomenclature) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: chapter.goods_nomenclature_item_id }
+
+ it 'returns not found' do
+ expect { get :show, id: chapter.goods_nomenclature_item_id.first(2), format: :json }.to raise_error Sequel::RecordNotFound
+ end
+ end
end
View
8 spec/controllers/api/v1/commodities_controller_spec.rb
@@ -32,4 +32,12 @@
expect { get :show, id: "1234567890", format: :json }.to raise_error Sequel::RecordNotFound
end
end
+
+ context 'when record is hidden' do
+ let!(:hidden_goods_nomenclature) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: commodity.goods_nomenclature_item_id }
+
+ it 'returns not found' do
+ expect { get :show, id: commodity.goods_nomenclature_item_id, format: :json }.to raise_error Sequel::RecordNotFound
+ end
+ end
end
View
24 spec/controllers/api/v1/headings_controller_spec.rb
@@ -21,11 +21,25 @@
context 'when record is present' do
it 'returns rendered record' do
get :show, id: heading, format: :json
-
response.body.should match_json_expression pattern
end
end
+ context 'when record is present and commodity has hidden commodities' do
+ let!(:commodity1) { create :commodity, :with_indent, :with_description, :with_chapter, :declarable, goods_nomenclature_item_id: "#{heading.short_code}010000"}
+ let!(:commodity2) { create :commodity, :with_indent, :with_description, :with_chapter, :declarable, goods_nomenclature_item_id: "#{heading.short_code}020000"}
+
+ let!(:hidden_goods_nomenclature) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: commodity2.goods_nomenclature_item_id }
+
+ it 'does not include hidden commodities in the response' do
+ get :show, id: heading, format: :json
+
+ body = JSON.parse(response.body)
+ body["commodities"].map{|c| c["goods_nomenclature_item_id"] }.should include commodity1.goods_nomenclature_item_id
+ body["commodities"].map{|c| c["goods_nomenclature_item_id"] }.should_not include commodity2.goods_nomenclature_item_id
+ end
+ end
+
context 'when record is not present' do
it 'returns not found if record was not found' do
expect { get :show, id: "5555", format: :json }.to raise_error Sequel::RecordNotFound
@@ -61,5 +75,13 @@
expect { get :show, id: "1234", format: :json }.to raise_error Sequel::RecordNotFound
end
end
+
+ context 'when record is hidden' do
+ let!(:hidden_goods_nomenclature) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: heading.goods_nomenclature_item_id }
+
+ it 'returns not found' do
+ expect { get :show, id: heading.goods_nomenclature_item_id.first(4), format: :json }.to raise_error Sequel::RecordNotFound
+ end
+ end
end
end
View
13 spec/factories/hidden_goods_nomenclature_factory.rb
@@ -0,0 +1,13 @@
+FactoryGirl.define do
+ factory :hidden_goods_nomenclature do
+ goods_nomenclature_item_id { 10.times.map{ Random.rand(9) }.join }
+
+ trait :chapter do
+ goods_nomenclature_item_id { "#{2.times.map{ Random.rand(9) }.join}00000000" }
+ end
+
+ trait :heading do
+ goods_nomenclature_item_id { "#{4.times.map{ Random.rand(8)+1 }.join}000000" }
+ end
+ end
+end
View
8 spec/models/chapter_spec.rb
@@ -13,6 +13,10 @@
let!(:heading3) { create :heading, goods_nomenclature_item_id: "#{chapter.goods_nomenclature_item_id.first(2)}30000000",
validity_start_date: 10.years.ago,
validity_end_date: 8.years.ago }
+ let!(:heading4) { create :heading, goods_nomenclature_item_id: "#{chapter.goods_nomenclature_item_id.first(2)}40000000",
+ validity_start_date: 10.years.ago,
+ validity_end_date: nil }
+ let!(:hidden_gono) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: heading4.goods_nomenclature_item_id }
around(:each) do |example|
TimeMachine.at(1.year.ago) do
@@ -31,6 +35,10 @@
it 'does not return heading that is irrelevant to given time' do
chapter.headings.should_not include heading3
end
+
+ it 'does not include hidden commodity' do
+ chapter.headings.should_not include heading4
+ end
end
end
View
15 spec/models/hidden_goods_nomenclature_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe HiddenGoodsNomenclature do
+ it { should validate_presence.of(:goods_nomenclature_item_id) }
+
+ describe '.codes' do
+ let!(:hidden_gono1) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: "9900000000" }
+ let!(:hidden_gono2) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: "0101000000" }
+
+ it 'returns array of hidden codes' do
+ HiddenGoodsNomenclature.codes.should eq [hidden_gono2.goods_nomenclature_item_id,
+ hidden_gono1.goods_nomenclature_item_id]
+ end
+ end
+end
View
8 spec/models/section_spec.rb
@@ -1,6 +1,14 @@
require 'spec_helper'
describe Section do
+ describe 'associations' do
+ describe 'chapters' do
+ it 'does not include HiddenGoodsNomenclatures' do
+ pending
+ end
+ end
+ end
+
describe '.to_param' do
let(:section) { create :section }
View
26 spec/services/search_service_spec.rb
@@ -81,7 +81,7 @@
context 'commodities' do
let(:commodity) { create :commodity, :declarable }
- let(:heading) { create :heading, :declarable }
+ let(:heading) { create :heading, :declarable }
let(:commodity_pattern) {
{
type: 'exact_match',
@@ -147,6 +147,30 @@
result.should match_json_expression heading_pattern
end
end
+
+ context 'hidden commodities' do
+ let!(:commodity) { create :commodity, :declarable }
+ let!(:hidden_gono) { create :hidden_goods_nomenclature, goods_nomenclature_item_id: commodity.goods_nomenclature_item_id }
+
+ let(:commodity_pattern) {
+ {
+ type: 'exact_match',
+ entry: {
+ endpoint: 'commodities',
+ id: commodity.goods_nomenclature_item_id.first(10)
+ }
+ }
+ }
+
+ before {
+ @result = SearchService.new(t: commodity.goods_nomenclature_item_id.first(10),
+ as_of: Date.today).to_json
+ }
+
+ it 'does not return hidden commodity as exact match' do
+ @result.should_not match_json_expression commodity_pattern
+ end
+ end
end
# Searching in ElasticSearch index
Something went wrong with that request. Please try again.