enju_inventory 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +11 -0
  3. data/app/controllers/inventory_files_controller.rb +10 -1
  4. data/app/models/inventory.rb +38 -11
  5. data/app/models/inventory_file.rb +34 -5
  6. data/app/views/inventory_files/_form.html.erb +23 -0
  7. data/app/views/inventory_files/_observe_field.html.erb +7 -0
  8. data/app/views/inventory_files/_results.html.erb +36 -0
  9. data/app/views/inventory_files/edit.html.erb +3 -33
  10. data/app/views/inventory_files/index.html.erb +2 -4
  11. data/app/views/inventory_files/new.html.erb +3 -14
  12. data/app/views/inventory_files/show.html.erb +44 -35
  13. data/config/locales/translation_en.yml +5 -1
  14. data/config/locales/translation_ja.yml +5 -1
  15. data/db/migrate/20191224083828_add_item_identifier_to_inventory.rb +6 -0
  16. data/db/migrate/20191224091957_add_current_shelf_name_to_inventory.rb +6 -0
  17. data/db/migrate/20191230082846_add_shelf_to_inventory_file.rb +5 -0
  18. data/lib/enju_inventory/version.rb +1 -1
  19. data/lib/generators/enju_inventory/setup/USAGE +8 -0
  20. data/lib/generators/enju_inventory/setup/setup_generator.rb +13 -0
  21. data/spec/controllers/inventories_controller_spec.rb +4 -4
  22. data/spec/controllers/inventory_files_controller_spec.rb +5 -6
  23. data/spec/controllers/items_controller_spec.rb +1 -1
  24. data/spec/dummy/app/models/application_record.rb +3 -0
  25. data/spec/dummy/db/migrate/005_create_manifestations.rb +3 -3
  26. data/spec/dummy/db/migrate/132_create_circulation_statuses.rb +16 -0
  27. data/spec/dummy/db/migrate/20130416054135_add_circulation_status_id_to_item.rb +8 -0
  28. data/spec/dummy/db/migrate/20180107161311_add_constraints_to_most_recent_for_agent_import_file_transitions.rb +1 -1
  29. data/spec/dummy/db/migrate/20180107161331_add_constraints_to_most_recent_for_resource_import_file_transitions.rb +1 -1
  30. data/spec/dummy/db/migrate/20180107161347_add_constraints_to_most_recent_for_resource_export_file_transitions.rb +1 -1
  31. data/spec/dummy/db/migrate/20180107161410_add_constraints_to_most_recent_for_import_request_transitions.rb +1 -1
  32. data/spec/dummy/db/migrate/20190818075603_add_memo_to_manifestation.rb +5 -0
  33. data/spec/dummy/db/migrate/20190818075628_add_memo_to_item.rb +5 -0
  34. data/spec/dummy/db/migrate/20191219122214_create_custom_properties.rb +12 -0
  35. data/spec/dummy/db/schema.rb +31 -1
  36. data/spec/fixtures/carrier_types.yml +54 -0
  37. data/spec/fixtures/circulation_statuses.yml +119 -0
  38. data/spec/fixtures/content_types.yml +98 -0
  39. data/spec/fixtures/inventories.yml +8 -6
  40. data/spec/fixtures/inventory_files.yml +4 -0
  41. data/spec/fixtures/items.yml +316 -0
  42. data/spec/fixtures/manifestations.yml +1891 -0
  43. data/spec/fixtures/shelves.yml +46 -0
  44. data/spec/fixtures/users.yml +1 -1
  45. data/spec/models/inventory_file_spec.rb +7 -2
  46. data/spec/models/inventory_spec.rb +8 -6
  47. metadata +291 -218
  48. data/README.rdoc +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c4d50b7e15533f78ab52f9721131bfe8e2d0e6b8
4
- data.tar.gz: 977c970e7f16fbf01ecd99d5f0408dda975e4bc2
2
+ SHA256:
3
+ metadata.gz: '09b6a818e259d2e0e210cb2e3b3c89c67cdcf797ba7aa992e58155844578335c'
4
+ data.tar.gz: d11633b8f3cd04fb6e794c4735b9d399b651db6c668251a8e2c52e607132c11c
5
5
  SHA512:
6
- metadata.gz: f4b3690aff8c0c36c109e39b2773c2cc84c1a6ff0b7615cdc79955e1611026277c3fcc9f51f0f2aa2cf62ba4d12310918adafd9666e4224cb69c4d39d03c9809
7
- data.tar.gz: 7d1da914990a234ab0137652557c2bebc3d3a4d0c88b169f36cbdf65cc5993216e197c12b707f375ae2c2200f449f0847077476e4d9a724ff474d502cdd7d28e
6
+ metadata.gz: fe5a4047cc652ac45a71b364d91760562b5502e2b0038017e553c37d1bacfafadf19d086271ff032e89d9c66f165cd5c6d39c90ced51e0ba1cfde72354b0ffca
7
+ data.tar.gz: 0654e486b8d1d3feff510fa0e185e603dfcc9e786e6d89c6859f1948e6247546a417bcb9cd92f527c2cd38ed4912e5136c71444157144ab606b86f38ed0c9353
@@ -0,0 +1,11 @@
1
+ # EnjuEvent
2
+ [![Travis CI](https://travis-ci.com/next-l/enju_inventory.svg?branch=1.3)](https://travis-ci.com/next-l/enju_inventory)
3
+ [![Coverage Status](https://coveralls.io/repos/github/next-l/enju_inventory/badge.svg?branch=1.3)](https://coveralls.io/github/next-l/enju_inventory?branch=1.3)
4
+ [![security](https://hakiri.io/github/next-l/enju_inventory/1.3.svg)](https://hakiri.io/github/next-l/enju_inventory/1.3)
5
+
6
+ This project rocks and uses MIT-LICENSE.
7
+
8
+ ## 製作者・貢献者 (Authors and contributors)
9
+ * [TANABE, Kosuke](https://github.com/nabeta) ([@nabeta](https://twitter.com/nabeta))
10
+ * [Project Next-L](https://www.next-l.jp) ([@ProjectNextL](https://twitter.com/ProjectNextL))
11
+
@@ -1,6 +1,7 @@
1
1
  class InventoryFilesController < ApplicationController
2
2
  before_action :set_inventory_file, only: [:show, :edit, :update, :destroy]
3
3
  before_action :check_policy, only: [:index, :new, :create]
4
+ before_action :prepare_options, only: [:new, :edit]
4
5
 
5
6
  # GET /inventory_files
6
7
  # GET /inventory_files.json
@@ -21,6 +22,7 @@ class InventoryFilesController < ApplicationController
21
22
  file = @inventory_file.inventory.path
22
23
  end
23
24
  end
25
+ @inventories = @inventory_file.inventories.page(params[:page])
24
26
 
25
27
  respond_to do |format|
26
28
  format.html # show.html.erb
@@ -64,6 +66,7 @@ class InventoryFilesController < ApplicationController
64
66
  format.html { redirect_to(@inventory_file) }
65
67
  format.json { render json: @inventory_file, status: :created, location: @inventory_file }
66
68
  else
69
+ prepare_options
67
70
  format.html { render action: "new" }
68
71
  format.json { render json: @inventory_file.errors, status: :unprocessable_entity }
69
72
  end
@@ -79,6 +82,7 @@ class InventoryFilesController < ApplicationController
79
82
  format.html { redirect_to(@inventory_file) }
80
83
  format.json { head :no_content }
81
84
  else
85
+ prepare_options
82
86
  format.html { render action: "edit" }
83
87
  format.json { render json: @inventory_file.errors, status: :unprocessable_entity }
84
88
  end
@@ -106,7 +110,12 @@ class InventoryFilesController < ApplicationController
106
110
  authorize InventoryFile
107
111
  end
108
112
 
113
+ def prepare_options
114
+ @libraries = Library.order(:position)
115
+ @shelves = Shelf.order(:position)
116
+ end
117
+
109
118
  def inventory_file_params
110
- params.require(:inventory_file).permit(:inventory, :note)
119
+ params.require(:inventory_file).permit(:inventory, :shelf_id, :note)
111
120
  end
112
121
  end
@@ -1,22 +1,49 @@
1
- class Inventory < ActiveRecord::Base
2
- belongs_to :item
1
+ class Inventory < ApplicationRecord
2
+ belongs_to :item, optional: true
3
3
  belongs_to :inventory_file
4
4
 
5
- validates_associated :item, :inventory_file
6
- validates_presence_of :item, :inventory_file
7
- validates_uniqueness_of :item_id, scope: :inventory_file_id
5
+ validates :item_identifier, :current_shelf_name, presence: true
6
+ validates :item_id, :item_identifier, uniqueness: {scope: :inventory_file_id}
8
7
 
9
8
  paginates_per 10
9
+
10
+ def to_hash
11
+ {
12
+ created_at: created_at,
13
+ identifier: item_identifier,
14
+ item_identifier: item.try(:item_identifier),
15
+ current_shelf: current_shelf_name,
16
+ shelf: item.try(:shelf),
17
+ call_number: item.try(:call_number),
18
+ circulation_status: item.try(:circulation_status).try(:name),
19
+ title: item.try(:manifestation).try(:original_title),
20
+ extent: item.try(:manifestation).try(:extent)
21
+ }
22
+ end
23
+
24
+ def lost
25
+ item.circulation_status = CirculationStatus.find_by(name: 'Missing')
26
+ end
27
+
28
+ def found
29
+ if item.rended?
30
+ item.circulation_status = CirculationStatus.find_by(name: 'On Loan')
31
+ else
32
+ item.circulation_status = CirculationStatus.find_by(name: 'Available On Shelf')
33
+ end
34
+ end
10
35
  end
11
36
 
12
37
  # == Schema Information
13
38
  #
14
39
  # Table name: inventories
15
40
  #
16
- # id :integer not null, primary key
17
- # item_id :integer
18
- # inventory_file_id :integer
19
- # note :text
20
- # created_at :datetime
21
- # updated_at :datetime
41
+ # id :integer not null, primary key
42
+ # item_id :integer
43
+ # inventory_file_id :integer
44
+ # note :text
45
+ # created_at :datetime
46
+ # updated_at :datetime
47
+ # item_identifier :string
48
+ # current_shelf_name :string
22
49
  #
@@ -1,8 +1,8 @@
1
- class InventoryFile < ActiveRecord::Base
1
+ class InventoryFile < ApplicationRecord
2
2
  has_many :inventories, dependent: :destroy
3
3
  has_many :items, through: :inventories
4
4
  belongs_to :user
5
- validates_presence_of :user
5
+ belongs_to :shelf
6
6
 
7
7
  if ENV['ENJU_STORAGE'] == 's3'
8
8
  has_attached_file :inventory, storage: :s3,
@@ -17,7 +17,8 @@ class InventoryFile < ActiveRecord::Base
17
17
  path: ":rails_root/private/system/:class/:attachment/:id_partition/:style/:filename"
18
18
  end
19
19
  validates_attachment_content_type :inventory, content_type: ['text/csv', 'text/plain', 'text/tab-separated-values']
20
- validates_attachment_presence :inventory
20
+ validates_attachment_presence :inventory, on: :create
21
+ attr_accessor :library_id
21
22
 
22
23
  paginates_per 10
23
24
 
@@ -26,16 +27,43 @@ class InventoryFile < ActiveRecord::Base
26
27
  file = File.open(self.inventory.path)
27
28
  reader = file.read
28
29
  reader.split.each do |row|
29
- item = Item.where(item_identifier: row.to_s.strip).first
30
+ identifier = row.to_s.strip
31
+ item = Item.find_by(item_identifier: identifier)
30
32
  if item
31
33
  unless self.items.where(id: item.id).select('items.id').first
32
- self.items << item
34
+ Inventory.create(
35
+ inventory_file: self,
36
+ item: item,
37
+ current_shelf_name: shelf.name,
38
+ item_identifier: identifier
39
+ )
33
40
  end
34
41
  end
35
42
  end
36
43
  file.close
37
44
  true
38
45
  end
46
+
47
+ def export(col_sep: "\t")
48
+ file = Tempfile.create('inventory_file') do |f|
49
+ inventories.each do |inventory|
50
+ f.write inventory.to_hash.values.to_csv(col_sep)
51
+ end
52
+
53
+ f.rewind
54
+ f.read
55
+ end
56
+
57
+ file
58
+ end
59
+
60
+ def missing_items
61
+ Item.where(Inventory.where('items.id = inventories.item_id AND inventories.inventory_file_id = ?', id).exists.not)
62
+ end
63
+
64
+ def found_items
65
+ items
66
+ end
39
67
  end
40
68
 
41
69
  # == Schema Information
@@ -55,4 +83,5 @@ end
55
83
  # inventory_file_size :integer
56
84
  # inventory_updated_at :datetime
57
85
  # inventory_fingerprint :string
86
+ # shelf_id :integer
58
87
  #
@@ -0,0 +1,23 @@
1
+ <%= form_for(@inventory_file) do |f| -%>
2
+ <%= f.error_messages -%>
3
+
4
+ <div class="field">
5
+ <%= f.label "#{t('activerecord.models.library')} / #{t('activerecord.models.shelf')}" -%>
6
+ <%= f.select :library_id, @libraries.map{|l| [l.display_name.localize, l.id]} %>
7
+ <%= f.select :shelf_id, @shelves.map{|s| [s.display_name.localize, s.id]} %>
8
+ <%= render 'observe_field' %>
9
+ </div>
10
+
11
+ <div class="field">
12
+ <%= f.label t('page.file') -%><br />
13
+ <%= f.file_field :inventory -%>
14
+ </div>
15
+
16
+ <div class="field">
17
+ <%= f.label :note -%> <br />
18
+ <%= f.text_area :note -%>
19
+ </div>
20
+ <div class="actions">
21
+ <%= f.submit %>
22
+ </div>
23
+ <%- end -%>
@@ -0,0 +1,7 @@
1
+ <script type="text/javascript">
2
+ function displayVals() {
3
+ var libraryValue = $("#inventory_file_library_id").val();
4
+ $("#inventory_file_shelf_id").load('<%= shelves_path %>?mode=select&library_id=' + libraryValue);
5
+ }
6
+ $("#inventory_file_library_id").change(displayVals);
7
+ </script>
@@ -0,0 +1,36 @@
1
+ <h2><%= t('activerecord.models.inventory') %></h2>
2
+
3
+ <p>
4
+ <%= link_to((image_tag 'icons/page_white_excel.png', size: '16x16', alt: 'TSV', class: 'enju_icon'), inventories_path(inventory_file_id: @inventory_file.id, format: :txt)) -%>
5
+ (<%= link_to 'TSV', inventories_path(inventory_file_id: @inventory_file.id, format: :txt) -%>)
6
+ </p>
7
+
8
+ <table class="table table-striped index">
9
+ <tr>
10
+ <th><%= t('activerecord.attributes.inventory.lineno') %></th>
11
+ <th><%= t('activerecord.attributes.inventory.current_shelf_name') %></th>
12
+ <th><%= t('activerecord.attributes.inventory.item_identifier') %></th>
13
+ <th><%= t('activerecord.models.manifestation') %></th>
14
+ <th></th>
15
+ </tr>
16
+ <% @inventories.each_with_index do |inventory, idx| %>
17
+ <tr class="line<%= cycle("0", "1") -%>">
18
+ <td><%= @inventories.offset_value + idx + 1 %></td>
19
+ <td><%= inventory.current_shelf_name %></td>
20
+ <td><%= inventory.item_identifier %></td>
21
+ </td>
22
+ <td>
23
+ <% if inventory.item %>
24
+ <%= link_to inventory.item.item_identifier, inventory.item %>
25
+ <br />
26
+ <%= link_to inventory.item.manifestation.original_title, inventory.item.manifestation if inventory.item.try(:manifestation) %>
27
+ <% end %>
28
+ </td>
29
+ <td>
30
+ <%= link_to t('page.show'), inventory %>
31
+ <%= link_to t('page.destroy'), inventory, data: {confirm: t('page.are_you_sure')}, method: :delete %>
32
+ </td>
33
+ </tr>
34
+ <% end %>
35
+ </table>
36
+ <%= paginate(@inventories) %>
@@ -1,40 +1,10 @@
1
1
  <div id="content_detail" class="ui-corner-all ui-widget-content">
2
- <h1 class="title"><%= t('page.editing', :model => t('activerecord.models.inventory_file')) -%></h1>
3
- <div id="content_list">
2
+ <h1 class="title"><%= t('page.editing', :model => t('activerecord.models.inventory_file')) -%></h1>
3
+ <div id="content_list">
4
4
 
5
- <%= form_for(@inventory_file) do |f| -%>
6
- <%= f.error_messages -%>
5
+ <%= render 'form' %>
7
6
 
8
- <div class="field">
9
- <%= f.label :inventory_file_name -%> <br />
10
- <%= f.text_field :inventory_file_name -%>
11
7
  </div>
12
- <div class="field">
13
- <%= f.label :inventory_content_type -%> <br />
14
- <%= f.text_field :inventory_content_type -%>
15
- </div>
16
- <div class="field">
17
- <%= f.label :inventory_file_size -%> <br />
18
- <%= f.text_field :inventory_file_size -%>
19
- </div>
20
- <div class="field">
21
- <%= f.label :inventory_fingerprint -%> <br />
22
- <%= f.text_field :inventory_fingerprint -%>
23
- </div>
24
- <div class="field">
25
- <%= f.label :user_id -%> <br />
26
- <%= f.text_field :user_id -%>
27
- </div>
28
- <div class="field">
29
- <%= f.label :note -%> <br />
30
- <%= f.text_area :note -%>
31
- </div>
32
- <div class="actions">
33
- <%= f.submit %>
34
- </div>
35
- <%- end -%>
36
-
37
- </div>
38
8
  </div>
39
9
 
40
10
  <div id="submenu" class="ui-corner-all ui-widget-content">
@@ -4,24 +4,22 @@
4
4
 
5
5
  <table class="table table-striped index">
6
6
  <tr>
7
+ <th><%= t('activerecord.attributes.inventory_file.shelf') -%> </th>
7
8
  <th><%= t('activerecord.attributes.inventory_file.inventory_file_name') -%> </th>
8
- <th><%= t('activerecord.attributes.inventory_file.inventory_content_type') -%> </th>
9
9
  <th><%= t('activerecord.attributes.inventory_file.inventory_file_size') -%> </th>
10
- <th><%= t('activerecord.attributes.inventory_file.inventory_fingerprint') -%> </th>
11
10
  <th><%= t('activerecord.models.user') -%> </th>
12
11
  <th></th>
13
12
  </tr>
14
13
 
15
14
  <%- @inventory_files.each do |inventory_file| -%>
16
15
  <tr class="line<%= cycle("0", "1") -%>">
16
+ <td><%= link_to inventory_file.shelf.display_name, inventory_file.shelf %></td>
17
17
  <td>
18
18
  <%= link_to inventory_file.inventory_file_name, inventory_file -%>
19
19
  <br />
20
20
  <%= inventory_file.created_at -%>
21
21
  </td>
22
- <td><%= inventory_file.inventory_content_type -%> </td>
23
22
  <td><%= inventory_file.inventory_file_size -%> </td>
24
- <td><%= inventory_file.inventory_fingerprint -%> </td>
25
23
  <td><%= link_to inventory_file.user.username, inventory_file.user.profile if inventory_file.user.try(:profile) -%> </td>
26
24
  <td>
27
25
  <%= link_to t('page.edit'), edit_inventory_file_path(inventory_file) -%>
@@ -1,21 +1,10 @@
1
1
  <div id="content_detail" class="ui-corner-all ui-widget-content">
2
- <h1 class="title"><%= t('page.new', :model => t('activerecord.models.inventory_file')) -%> </h1>
3
- <div id="content_list">
2
+ <h1 class="title"><%= t('page.new', :model => t('activerecord.models.inventory_file')) -%> </h1>
3
+ <div id="content_list">
4
4
 
5
- <%= form_for(@inventory_file, :html => {:multipart => true}) do |f| -%>
6
- <%= f.error_messages -%>
5
+ <%= render 'form' %>
7
6
 
8
- <div class="field">
9
- <%= f.label t('page.file') -%><br />
10
- <%= f.file_field :inventory -%>
11
7
  </div>
12
-
13
- <div class="actions">
14
- <%= f.submit %>
15
- </div>
16
- <%- end -%>
17
-
18
- </div>
19
8
  </div>
20
9
 
21
10
  <div id="submenu" class="ui-corner-all ui-widget-content">
@@ -1,39 +1,48 @@
1
1
  <div id="content_detail" class="ui-corner-all ui-widget-content">
2
- <h1 class="title"><%= t('page.showing', :model => t('activerecord.models.inventory_file')) -%></h1>
3
- <div id="content_list">
4
- <p id="notice"><%= notice %></p>
5
-
6
- <p>
7
- <strong><%= t('activerecord.attributes.inventory_file.inventory_file_name') -%> :</strong>
8
- <%= @inventory_file.inventory_file_name -%>
9
- </p>
10
-
11
- <p>
12
- <strong><%= t('activerecord.attributes.inventory_file.inventory_content_type') -%> :</strong>
13
- <%= @inventory_file.inventory_content_type -%>
14
- </p>
15
-
16
- <p>
17
- <strong><%= t('activerecord.attributes.inventory_file.inventory_file_size') -%> :</strong>
18
- <%= @inventory_file.inventory_file_size -%>
19
- </p>
20
-
21
- <p>
22
- <strong><%= t('activerecord.attributes.inventory_file.inventory_fingerprint') -%> :</strong>
23
- <%= @inventory_file.inventory_fingerprint -%>
24
- </p>
25
-
26
- <p>
27
- <strong><%= t('activerecord.models.user') -%> :</strong>
28
- <%= link_to @inventory_file.user.username, @inventory_file.user.profile if @inventory_file.user.try(:profile) -%>
29
- </p>
30
-
31
- <p>
32
- <strong><%= t('activerecord.attributes.inventory_file.note') -%> :</strong>
33
- <%= @inventory_file.note -%>
34
- </p>
35
-
36
- </div>
2
+ <h1 class="title"><%= t('page.showing', :model => t('activerecord.models.inventory_file')) -%></h1>
3
+ <div id="content_list">
4
+ <p id="notice"><%= notice %></p>
5
+
6
+ <p>
7
+ <strong><%= t('activerecord.attributes.inventory_file.shelf') -%> :</strong>
8
+ <%= link_to @inventory_file.shelf.display_name, @inventory_file.shelf -%>
9
+ </p>
10
+
11
+ <p>
12
+ <strong><%= t('activerecord.attributes.inventory_file.inventory_file_name') -%> :</strong>
13
+ <%= @inventory_file.inventory_file_name -%>
14
+ </p>
15
+
16
+ <p>
17
+ <strong><%= t('activerecord.attributes.inventory_file.inventory_content_type') -%> :</strong>
18
+ <%= @inventory_file.inventory_content_type -%>
19
+ </p>
20
+
21
+ <p>
22
+ <strong><%= t('activerecord.attributes.inventory_file.inventory_file_size') -%> :</strong>
23
+ <%= @inventory_file.inventory_file_size -%>
24
+ </p>
25
+
26
+ <p>
27
+ <strong><%= t('activerecord.attributes.inventory_file.inventory_fingerprint') -%> :</strong>
28
+ <%= @inventory_file.inventory_fingerprint -%>
29
+ </p>
30
+
31
+ <p>
32
+ <strong><%= t('activerecord.models.user') -%> :</strong>
33
+ <%= link_to @inventory_file.user.username, @inventory_file.user.profile if @inventory_file.user.try(:profile) -%>
34
+ </p>
35
+
36
+ <p>
37
+ <strong><%= t('activerecord.attributes.inventory_file.note') -%> :</strong>
38
+ <%= @inventory_file.note -%>
39
+ </p>
40
+
41
+ <% if @inventories %>
42
+ <%= render 'results' %>
43
+ <% end %>
44
+
45
+ </div>
37
46
  </div>
38
47
 
39
48
  <div id="submenu" class="ui-corner-all ui-widget-content">