enju_circulation 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/checkins_controller.rb +2 -2
  3. data/app/models/checkin.rb +1 -1
  4. data/app/models/checkout.rb +2 -2
  5. data/app/models/checkout_stat_has_user.rb +1 -1
  6. data/app/models/concerns/enju_circulation/enju_item.rb +2 -0
  7. data/app/models/lending_policy.rb +3 -3
  8. data/app/models/manifestation_checkout_stat_transition.rb +1 -1
  9. data/app/models/manifestation_reserve_stat_transition.rb +1 -1
  10. data/app/models/reserve.rb +4 -4
  11. data/app/models/reserve_state_machine.rb +2 -3
  12. data/app/models/reserve_transition.rb +1 -1
  13. data/app/models/user_checkout_stat_transition.rb +1 -1
  14. data/app/models/user_group_has_checkout_type.rb +6 -6
  15. data/app/models/user_reserve_stat_transition.rb +1 -1
  16. data/lib/enju_circulation/version.rb +1 -1
  17. data/spec/controllers/checkins_controller_spec.rb +130 -8
  18. data/spec/controllers/withdraws_controller_spec.rb +26 -0
  19. data/spec/dummy/db/migrate/20200425072340_create_manifestation_custom_properties.rb +12 -0
  20. data/spec/dummy/db/migrate/20200425072349_create_item_custom_properties.rb +12 -0
  21. data/spec/dummy/db/migrate/20200425074758_create_manifestation_custom_values.rb +12 -0
  22. data/spec/dummy/db/migrate/20200425074822_create_item_custom_values.rb +12 -0
  23. data/spec/dummy/db/schema.rb +43 -10
  24. data/spec/fixtures/checkins.yml +1 -1
  25. data/spec/fixtures/checkout_stat_has_users.yml +1 -1
  26. data/spec/fixtures/checkouts.yml +2 -2
  27. data/spec/fixtures/lending_policies.yml +3 -3
  28. data/spec/fixtures/reserve_transitions.yml +1 -1
  29. data/spec/fixtures/reserves.yml +3 -3
  30. data/spec/fixtures/user_group_has_checkout_types.yml +6 -6
  31. data/spec/models/checkin_spec.rb +1 -1
  32. data/spec/models/checkout_spec.rb +2 -2
  33. data/spec/models/checkout_stat_has_user_spec.rb +1 -1
  34. data/spec/models/lending_policy_spec.rb +3 -3
  35. data/spec/models/reserve_spec.rb +3 -3
  36. data/spec/models/user_group_has_checkout_type_spec.rb +6 -6
  37. metadata +383 -347
  38. data/spec/dummy/db/migrate/20191219122214_create_custom_properties.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35ebe6b31ee4582069cb7065b429f5a6a54ce1eac81b5af60aa60d11cd774b08
4
- data.tar.gz: 5efc3f26f9703fd0b3bdcf1304b4efaa25364a8effaaa29bb44de4ca0f6af8fd
3
+ metadata.gz: 8acae0635971690b1966d9ec8c5c3f5c608528c624feb76f201ce0cc90b473e4
4
+ data.tar.gz: 60815d7876aee8efe0aba781e33cc919c2ff5af9830761dc1aff778398522bea
5
5
  SHA512:
6
- metadata.gz: c9156fbb9c9d3869ac1ff16d50c186198a8b7dc1db214b571fbc3df857e8f72f10aa3ad03b693efbf20930649aea90eeac58f93f90cce1b6dcaf85a2a0ed7690
7
- data.tar.gz: 2c4523ae4c13ada69225b8173a160cfece61b879dd2c39ffedc70524666ef442eb44108ea362a2cf2865e4d2ce0ca80a6aec950996f0fc713042b549248f35a6
6
+ metadata.gz: ec55abc5f36563dbba595a2984564c1f8f45911acf3fc24fdcddba3c4f0b0b3d66981081638a4ff7d768122ba510196e49d2546af9b4522b928d39d9aad6b1fe
7
+ data.tar.gz: fc0727906cdea3789852dbee7c97684b600f4ca0b5aa143a8c75caff5c5f0f104a3ec6d284bb92c76a3d99121c974261341924a4d3450e94162c0dcde6fd5b9c
@@ -77,12 +77,12 @@ class CheckinsController < ApplicationController
77
77
  end
78
78
  flash[:message] << message if message
79
79
  format.html { redirect_to checkins_url(basket_id: @checkin.basket_id) }
80
- format.json { render json: @checkin, status: :created, location: @checkin }
80
+ format.json { render json: {result: @checkin, messages: flash[:message]}, status: :created, location: @checkin }
81
81
  format.js { redirect_to checkins_url(basket_id: @basket.id, format: :js) }
82
82
  else
83
83
  @checkins = @basket.checkins.page(1)
84
84
  format.html { render action: "new" }
85
- format.json { render json: @checkin.errors, status: :unprocessable_entity }
85
+ format.json { render json: {messages: @checkin.errors}, status: :unprocessable_entity }
86
86
  format.js { render action: "index" }
87
87
  end
88
88
  end
@@ -91,5 +91,5 @@ end
91
91
  # basket_id :integer
92
92
  # created_at :datetime
93
93
  # updated_at :datetime
94
- # lock_version :integer default(0), not null
94
+ # lock_version :integer default("0"), not null
95
95
  #
@@ -174,8 +174,8 @@ end
174
174
  # librarian_id :integer
175
175
  # basket_id :integer
176
176
  # due_date :datetime
177
- # checkout_renewal_count :integer default(0), not null
178
- # lock_version :integer default(0), not null
177
+ # checkout_renewal_count :integer default("0"), not null
178
+ # lock_version :integer default("0"), not null
179
179
  # created_at :datetime
180
180
  # updated_at :datetime
181
181
  # shelf_id :integer
@@ -17,7 +17,7 @@ end
17
17
  # id :integer not null, primary key
18
18
  # user_checkout_stat_id :integer not null
19
19
  # user_id :integer not null
20
- # checkouts_count :integer default(0), not null
20
+ # checkouts_count :integer default("0"), not null
21
21
  # created_at :datetime
22
22
  # updated_at :datetime
23
23
  #
@@ -105,6 +105,8 @@ module EnjuCirculation
105
105
  manifestation.next_reservation.transition_to!(:completed)
106
106
  manifestation.reload
107
107
  end
108
+
109
+ reload
108
110
  update!(circulation_status: CirculationStatus.find_by(name: 'On Loan'))
109
111
  end
110
112
 
@@ -19,10 +19,10 @@ end
19
19
  # id :integer not null, primary key
20
20
  # item_id :integer not null
21
21
  # user_group_id :integer not null
22
- # loan_period :integer default(0), not null
22
+ # loan_period :integer default("0"), not null
23
23
  # fixed_due_date :datetime
24
- # renewal :integer default(0), not null
25
- # fine :integer default(0), not null
24
+ # renewal :integer default("0"), not null
25
+ # fine :integer default("0"), not null
26
26
  # note :text
27
27
  # position :integer
28
28
  # created_at :datetime
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # manifestation_checkout_stat_id :integer
18
18
  # created_at :datetime
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # manifestation_reserve_stat_id :integer
18
18
  # created_at :datetime
@@ -2,7 +2,7 @@ class Reserve < ApplicationRecord
2
2
  include Statesman::Adapters::ActiveRecordQueries
3
3
  scope :hold, -> { where('item_id IS NOT NULL') }
4
4
  scope :not_hold, -> { where(item_id: nil) }
5
- scope :waiting, -> {not_in_state(:completed, :expired, :retained).where('canceled_at IS NULL AND (expired_at > ? OR expired_at IS NULL)', Time.zone.now).order('reserves.id DESC')}
5
+ scope :waiting, -> {not_in_state(:completed, :expired).where('canceled_at IS NULL AND (expired_at > ? OR expired_at IS NULL)', Time.zone.now).order('reserves.id DESC')}
6
6
  scope :retained, -> {in_state(:retained).where('retained_at IS NOT NULL')}
7
7
  scope :completed, -> {in_state(:completed).where('checked_out_at IS NOT NULL')}
8
8
  scope :canceled, -> {in_state(:canceled).where('canceled_at IS NOT NULL')}
@@ -404,10 +404,10 @@ end
404
404
  # canceled_at :datetime
405
405
  # expired_at :datetime
406
406
  # deleted_at :datetime
407
- # expiration_notice_to_patron :boolean default(FALSE)
408
- # expiration_notice_to_library :boolean default(FALSE)
407
+ # expiration_notice_to_patron :boolean default("0")
408
+ # expiration_notice_to_library :boolean default("0")
409
409
  # pickup_location_id :integer
410
410
  # retained_at :datetime
411
411
  # postponed_at :datetime
412
- # lock_version :integer default(0), not null
412
+ # lock_version :integer default("0"), not null
413
413
  #
@@ -14,16 +14,15 @@ class ReserveStateMachine
14
14
  transition from: :requested, to: [:retained, :canceled, :expired, :completed]
15
15
 
16
16
  after_transition(to: :requested) do |reserve|
17
- reserve.update(request_status_type: RequestStatusType.where(name: 'In Process').first, item_id: nil, retained_at: nil)
17
+ reserve.update(request_status_type: RequestStatusType.find_by(name: 'In Process'), item_id: nil, retained_at: nil)
18
18
  end
19
19
 
20
20
  after_transition(to: :retained) do |reserve|
21
21
  # TODO: 「取り置き中」の状態を正しく表す
22
- reserve.update(request_status_type: RequestStatusType.where(name: 'In Process').first, retained_at: Time.zone.now)
22
+ reserve.update(request_status_type: RequestStatusType.find_by(name: 'In Process'), retained_at: Time.zone.now)
23
23
  Reserve.transaction do
24
24
  if reserve.item
25
25
  other_reserves = reserve.item.reserves.waiting
26
- other_reserves += reserve.item.reserves.in_state(:retained)
27
26
  other_reserves.each{|r|
28
27
  if r != reserve
29
28
  r.transition_to!(:postponed)
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # reserve_id :integer
18
18
  # created_at :datetime
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # user_checkout_stat_id :integer
18
18
  # created_at :datetime
@@ -71,12 +71,12 @@ end
71
71
  # id :integer not null, primary key
72
72
  # user_group_id :integer not null
73
73
  # checkout_type_id :integer not null
74
- # checkout_limit :integer default(0), not null
75
- # checkout_period :integer default(0), not null
76
- # checkout_renewal_limit :integer default(0), not null
77
- # reservation_limit :integer default(0), not null
78
- # reservation_expired_period :integer default(7), not null
79
- # set_due_date_before_closing_day :boolean default(FALSE), not null
74
+ # checkout_limit :integer default("0"), not null
75
+ # checkout_period :integer default("0"), not null
76
+ # checkout_renewal_limit :integer default("0"), not null
77
+ # reservation_limit :integer default("0"), not null
78
+ # reservation_expired_period :integer default("7"), not null
79
+ # set_due_date_before_closing_day :boolean default("0"), not null
80
80
  # fixed_due_date :datetime
81
81
  # note :text
82
82
  # position :integer
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # user_reserve_stat_id :integer
18
18
  # created_at :datetime
@@ -1,3 +1,3 @@
1
1
  module EnjuCirculation
2
- VERSION = "0.3.8".freeze
2
+ VERSION = "0.3.9".freeze
3
3
  end
@@ -201,14 +201,14 @@ describe CheckinsController do
201
201
  it 'redirects to the created checkin' do
202
202
  post :create, params: { checkin: @attrs, basket_id: 9 }
203
203
  response.should redirect_to(checkins_url(basket_id: assigns(:checkin).basket_id))
204
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
204
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
205
205
  end
206
206
 
207
207
  it 'should checkin the overdue item' do
208
208
  post :create, params: { checkin: { item_identifier: '00014' }, basket_id: 9 }
209
209
  response.should redirect_to(checkins_url(basket_id: assigns(:checkin).basket_id))
210
210
  assigns(:checkin).checkout.should be_valid
211
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
211
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
212
212
  end
213
213
  end
214
214
  end
@@ -249,14 +249,14 @@ describe CheckinsController do
249
249
  it 'should show notification when it is reserved' do
250
250
  post :create, params: { checkin: { item_identifier: '00008' }, basket_id: 9 }
251
251
  flash[:message].to_s.index(I18n.t('item.this_item_is_reserved')).should be_truthy
252
- assigns(:checkin).item.should be_retained
253
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
252
+ assigns(:checkin).checkout.item.should be_retained
253
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
254
254
  response.should redirect_to(checkins_url(basket_id: assigns(:basket).id))
255
255
  end
256
256
 
257
257
  it 'should show notification when an item includes supplements' do
258
258
  post :create, params: { checkin: { item_identifier: '00004' }, basket_id: 9 }
259
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
259
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
260
260
  flash[:message].to_s.index(I18n.t('item.this_item_include_supplement')).should be_truthy
261
261
  response.should redirect_to(checkins_url(basket_id: assigns(:basket).id))
262
262
  end
@@ -306,6 +306,128 @@ describe CheckinsController do
306
306
  end
307
307
  end
308
308
 
309
+ describe 'POST create (json format)' do
310
+ before(:each) do
311
+ @attrs = { item_identifier: '00003' }
312
+ @invalid_attrs = { item_identifier: 'invalid' }
313
+ request.env["HTTP_ACCEPT"] = 'application/json'
314
+ end
315
+
316
+ describe 'When logged in as Administrator' do
317
+ login_fixture_admin
318
+
319
+ describe 'with valid params' do
320
+ it 'assigns a newly created checkin as @checkin' do
321
+ post :create, params: { checkin: @attrs }
322
+ assigns(:checkin).should be_nil
323
+ end
324
+
325
+ it 'should not create checkin without basket_id' do
326
+ post :create, params: { checkin: @attrs }
327
+ json = JSON.parse(response.body)
328
+ expect(json['error']).to eq('forbidden')
329
+ end
330
+
331
+ describe 'When basket_id is specified' do
332
+ it 'redirects to the created checkin' do
333
+ post :create, params: { checkin: @attrs, basket_id: 9 }
334
+ expect(response).to have_http_status(:created)
335
+ json = JSON.parse(response.body)
336
+ expect(json['result']['basket_id']).to eq(9)
337
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
338
+ end
339
+
340
+ it 'should checkin the overdue item' do
341
+ post :create, params: { checkin: { item_identifier: '00014' }, basket_id: 9 }
342
+ expect(response).to have_http_status(:created)
343
+ assigns(:checkin).checkout.should be_valid
344
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
345
+ end
346
+ end
347
+ end
348
+
349
+ describe 'with invalid params' do
350
+ it 'assigns a newly created but unsaved checkin as @checkin' do
351
+ post :create, params: { checkin: @invalid_attrs }
352
+ assigns(:checkin).should be_nil
353
+ end
354
+
355
+ it 'should be forbidden' do
356
+ post :create, params: { checkin: @invalid_attrs }
357
+ json = JSON.parse(response.body)
358
+ expect(json['error']).to eq('forbidden')
359
+ end
360
+ end
361
+
362
+ it 'should not create checkin without item_id' do
363
+ post :create, params: { checkin: { item_identifier: nil }, basket_id: 9 }
364
+ assigns(:checkin).should_not be_valid
365
+ expect(response).to have_http_status(:unprocessable_entity)
366
+ json = JSON.parse(response.body)
367
+ expect(json['messages']['base']).to match_array([I18n.t('checkin.item_not_found')])
368
+ expect(json['messages']['item_id']).to match_array([I18n.t('errors.messages.blank')])
369
+ end
370
+ end
371
+
372
+ describe 'When logged in as Librarian' do
373
+ login_fixture_librarian
374
+
375
+ describe 'with valid params' do
376
+ it 'assigns a newly created checkin as @checkin' do
377
+ post :create, params: { checkin: @attrs }
378
+ assigns(:checkin).should be_nil
379
+ end
380
+
381
+ it 'should not create checkin without basket_id' do
382
+ post :create, params: { checkin: @attrs }
383
+ json = JSON.parse(response.body)
384
+ expect(json['error']).to eq('forbidden')
385
+ end
386
+
387
+ it 'should show notification when it is reserved' do
388
+ post :create, params: { checkin: { item_identifier: '00008' }, basket_id: 9 }
389
+ flash[:message].to_s.index(I18n.t('item.this_item_is_reserved')).should be_truthy
390
+ assigns(:checkin).checkout.item.should be_retained
391
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
392
+ expect(response).to have_http_status(:created)
393
+ end
394
+
395
+ it 'should show notification when an item includes supplements' do
396
+ post :create, params: { checkin: { item_identifier: '00004' }, basket_id: 9 }
397
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
398
+ flash[:message].to_s.index(I18n.t('item.this_item_include_supplement')).should be_truthy
399
+ expect(response).to have_http_status(:created)
400
+ end
401
+ end
402
+
403
+ it "should show notice when other library's item is checked in" do
404
+ sign_in users(:librarian2)
405
+ post :create, params: { checkin: { item_identifier: '00009' }, basket_id: 9 }
406
+ assigns(:checkin).should be_valid
407
+ flash[:message].to_s.index(I18n.t('checkin.other_library_item')).should be_truthy
408
+ expect(response).to have_http_status(:created)
409
+ end
410
+ end
411
+
412
+ describe 'When not logged in' do
413
+ before(:each) do
414
+ @attrs = { item_identifier: '00003' }
415
+ @invalid_attrs = { item_identifier: 'invalid' }
416
+ end
417
+
418
+ describe 'with valid params' do
419
+ it 'assigns a newly created checkin as @checkin' do
420
+ post :create, params: { checkin: @attrs }
421
+ end
422
+
423
+ it 'should redirect to new session url' do
424
+ post :create, params: { checkin: @attrs }
425
+ expect(response).to have_http_status(:ok)
426
+ end
427
+ end
428
+ end
429
+ end
430
+
309
431
  describe 'PUT update' do
310
432
  before(:each) do
311
433
  @checkin = checkins(:checkin_00001)
@@ -335,7 +457,7 @@ describe CheckinsController do
335
457
 
336
458
  it "re-renders the 'edit' template" do
337
459
  put :update, params: { id: @checkin.id, checkin: @invalid_attrs }
338
- response.should render_template('edit')
460
+ expect(response).to be_successful
339
461
  end
340
462
 
341
463
  it 'should not update checkin without item_identifier' do
@@ -364,12 +486,12 @@ describe CheckinsController do
364
486
  describe 'with invalid params' do
365
487
  it 'assigns the checkin as @checkin' do
366
488
  put :update, params: { id: @checkin.id, checkin: @invalid_attrs }
367
- assigns(:checkin).should_not be_valid
489
+ expect(assigns(:checkin)).not_to be_valid
368
490
  end
369
491
 
370
492
  it "re-renders the 'edit' template" do
371
493
  put :update, params: { id: @checkin.id, checkin: @invalid_attrs }
372
- response.should render_template('edit')
494
+ expect(response).to be_successful
373
495
  end
374
496
  end
375
497
  end
@@ -0,0 +1,26 @@
1
+ require 'rails_helper'
2
+
3
+ describe WithdrawsController do
4
+ fixtures :all
5
+ let(:valid_attributes) do
6
+ FactoryBot.build(:withdraw).attributes.with_indifferent_access
7
+ end
8
+ let(:valid_create_attributes) do
9
+ { basket_id: Basket.find(valid_attributes[:basket_id]).id,
10
+ withdraw: { item_identifier: Item.find(valid_attributes[:item_id]).item_identifier }}
11
+ end
12
+
13
+ describe 'POST create' do
14
+ describe 'When logged in as Administrator' do
15
+ login_fixture_admin
16
+
17
+ it 'should not withdraw a checked-out item' do
18
+ expect do
19
+ post :create, params: { basket_id: valid_create_attributes[:basket_id], withdraw: { item_identifier: reserves(:reserve_00014).item.item_identifier } }
20
+ end.to change(Withdraw, :count).by(0)
21
+ expect(assigns(:withdraw)).to be_a(Withdraw)
22
+ expect(response).to be_successful
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ class CreateManifestationCustomProperties < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :manifestation_custom_properties do |t|
4
+ t.string :name, null: false, comment: 'ラベル名', index: {unique: true}
5
+ t.text :display_name, null: false, comment: '表示名'
6
+ t.text :note, comment: '備考'
7
+ t.integer :position, default: 1, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class CreateItemCustomProperties < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :item_custom_properties do |t|
4
+ t.string :name, null: false, comment: 'ラベル名', index: {unique: true}
5
+ t.text :display_name, null: false, comment: '表示名'
6
+ t.text :note, comment: '備考'
7
+ t.integer :position, default: 1, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end