Skip to content

Commit

Permalink
add payment model
Browse files Browse the repository at this point in the history
  • Loading branch information
kaiomagalhaes committed Nov 20, 2023
1 parent 29bac0d commit 1650755
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 6 deletions.
53 changes: 53 additions & 0 deletions app/controllers/payments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class PaymentsController < ApplicationController
before_action :set_payment, only: %i[ show update destroy ]

# GET /payments
# GET /payments.json
def index
@payments = Payment.all
end

# GET /payments/1
# GET /payments/1.json
def show
end

# POST /payments
# POST /payments.json
def create
@payment = Payment.new(payment_params)

if @payment.save
render :show, status: :created, location: @payment
else
render json: @payment.errors, status: :unprocessable_entity
end
end

# PATCH/PUT /payments/1
# PATCH/PUT /payments/1.json
def update
if @payment.update(payment_params)
render :show, status: :ok, location: @payment
else
render json: @payment.errors, status: :unprocessable_entity
end
end

# DELETE /payments/1
# DELETE /payments/1.json
def destroy
@payment.destroy
end

private
# Use callbacks to share common setup or constraints between actions.
def set_payment
@payment = Payment.find(params[:id])
end

# Only allow a list of trusted parameters through.
def payment_params
params.require(:payment).permit(:date, :amount, :statement_of_work_id)
end
end
25 changes: 25 additions & 0 deletions app/models/payment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# == Schema Information
#
# Table name: payments
#
# id :bigint not null, primary key
# amount :float
# date :datetime
# created_at :datetime not null
# updated_at :datetime not null
# statement_of_work_id :bigint not null
#
# Indexes
#
# index_payments_on_statement_of_work_id (statement_of_work_id)
#
# Foreign Keys
#
# fk_rails_... (statement_of_work_id => statement_of_works.id)
#
class Payment < ApplicationRecord
belongs_to :statement_of_work

validates :amount, presence: true
validates :date, presence: true
end
11 changes: 6 additions & 5 deletions app/models/statement_of_work.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class StatementOfWork < ApplicationRecord
belongs_to :project
has_many :requirements, dependent: :destroy
has_many :time_entries, dependent: :destroy
has_many :payments

# existing validations
validates :start_date, presence: true
Expand All @@ -41,16 +42,16 @@ class StatementOfWork < ApplicationRecord
# custom validation for date range
validate :validate_date_range

scope :active_in_period, ->(start_date, end_date) { where('start_date <= ? AND end_date >= ?', end_date, start_date) }
scope :maintenance, -> { where(model: 'maintenance') }
scope :time_and_materials, -> { where(model: 'time_and_materials') }
scope :active_in_period, ->(start_date, end_date) { where("start_date <= ? AND end_date >= ?", end_date, start_date) }
scope :maintenance, -> { where(model: "maintenance") }
scope :time_and_materials, -> { where(model: "time_and_materials") }

private

def validate_date_range
return unless start_date && end_date && start_date >= end_date

errors.add(:start_date, 'must be before end date')
errors.add(:end_date, 'must be after start date')
errors.add(:start_date, "must be before end date")
errors.add(:end_date, "must be after start date")
end
end
2 changes: 2 additions & 0 deletions app/views/payments/_payment.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.extract! payment, :id, :date, :amount, :statement_of_work_id, :created_at, :updated_at
json.url payment_url(payment, format: :json)
1 change: 1 addition & 0 deletions app/views/payments/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @payments, partial: "payments/payment", as: :payment
1 change: 1 addition & 0 deletions app/views/payments/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.partial! "payments/payment", payment: @payment
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'sidekiq/cron/web'

Rails.application.routes.draw do
resources :payments
resources :assignments
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
if Rails.env.production?
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20231120173352_create_payments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreatePayments < ActiveRecord::Migration[7.0]
def change
create_table :payments do |t|
t.datetime :date
t.float :amount
t.references :statement_of_work, null: false, foreign_key: true

t.timestamps
end
end
end
12 changes: 11 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

125 changes: 125 additions & 0 deletions spec/controllers/payments_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
require 'rails_helper'

# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to specify the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
#
# Compared to earlier versions of this generator, there is very limited use of
# stubs and message expectations in this spec. Stubs are only used when there
# is no simpler way to get a handle on the object needed for the example.
# Message expectations are only used when there is no simpler way to specify
# that an instance is receiving a specific message.
#
# Also compared to earlier versions of this generator, there are no longer any
# expectations of assigns and templates rendered. These features have been
# removed from Rails core in Rails 5, but can be added back in via the
# `rails-controller-testing` gem.

RSpec.describe PaymentsController, type: :controller do

# This should return the minimal set of attributes required to create a valid
# Payment. As you add validations to Payment, be sure to
# adjust the attributes here as well.
let(:valid_attributes) {
skip("Add a hash of attributes valid for your model")
}

let(:invalid_attributes) {
skip("Add a hash of attributes invalid for your model")
}

# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# PaymentsController. Be sure to keep this updated too.
let(:valid_session) { {} }

describe "GET #index" do
it "returns a success response" do
payment = Payment.create! valid_attributes
get :index, params: {}, session: valid_session
expect(response).to be_successful
end
end

describe "GET #show" do
it "returns a success response" do
payment = Payment.create! valid_attributes
get :show, params: {id: payment.to_param}, session: valid_session
expect(response).to be_successful
end
end

describe "POST #create" do
context "with valid params" do
it "creates a new Payment" do
expect {
post :create, params: {payment: valid_attributes}, session: valid_session
}.to change(Payment, :count).by(1)
end

it "renders a JSON response with the new payment" do
post :create, params: {payment: valid_attributes}, session: valid_session
expect(response).to have_http_status(:created)
expect(response.content_type).to eq('application/json')
expect(response.location).to eq(payment_url(Payment.last))
end
end

context "with invalid params" do
it "renders a JSON response with errors for the new payment" do
post :create, params: {payment: invalid_attributes}, session: valid_session
expect(response).to have_http_status(:unprocessable_entity)
expect(response.content_type).to eq('application/json')
end
end
end

describe "PUT #update" do
context "with valid params" do
let(:new_attributes) {
skip("Add a hash of attributes valid for your model")
}

it "updates the requested payment" do
payment = Payment.create! valid_attributes
put :update, params: {id: payment.to_param, payment: new_attributes}, session: valid_session
payment.reload
skip("Add assertions for updated state")
end

it "renders a JSON response with the payment" do
payment = Payment.create! valid_attributes
put :update, params: {id: payment.to_param, payment: new_attributes}, session: valid_session
expect(response).to have_http_status(:ok)
expect(response.content_type).to eq('application/json')
end
end

context "with invalid params" do
it "renders a JSON response with errors for the payment" do
payment = Payment.create! valid_attributes
put :update, params: {id: payment.to_param, payment: invalid_attributes}, session: valid_session
expect(response).to have_http_status(:unprocessable_entity)
expect(response.content_type).to eq('application/json')
end
end
end

describe "DELETE #destroy" do
it "destroys the requested payment" do
payment = Payment.create! valid_attributes
expect {
delete :destroy, params: {id: payment.to_param}, session: valid_session
}.to change(Payment, :count).by(-1)
end
end

end
26 changes: 26 additions & 0 deletions spec/factories/payments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# == Schema Information
#
# Table name: payments
#
# id :bigint not null, primary key
# amount :float
# date :datetime
# created_at :datetime not null
# updated_at :datetime not null
# statement_of_work_id :bigint not null
#
# Indexes
#
# index_payments_on_statement_of_work_id (statement_of_work_id)
#
# Foreign Keys
#
# fk_rails_... (statement_of_work_id => statement_of_works.id)
#
FactoryBot.define do
factory :payment do
date { "2023-11-20 17:33:52" }
amount { 1.5 }
statement_of_work { nil }
end
end
31 changes: 31 additions & 0 deletions spec/models/payment_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# == Schema Information
#
# Table name: payments
#
# id :bigint not null, primary key
# amount :float
# date :datetime
# created_at :datetime not null
# updated_at :datetime not null
# statement_of_work_id :bigint not null
#
# Indexes
#
# index_payments_on_statement_of_work_id (statement_of_work_id)
#
# Foreign Keys
#
# fk_rails_... (statement_of_work_id => statement_of_works.id)
#
require "rails_helper"

RSpec.describe Payment, type: :model do
describe "associations" do
it { should belong_to(:statement_of_work) }
end

describe "validations" do
it { should validate_presence_of(:date) }
it { should validate_presence_of(:amount) }
end
end

0 comments on commit 1650755

Please sign in to comment.