Skip to content

Commit

Permalink
Merge pull request #33 from Nemwel-Boniface/eggs_resource
Browse files Browse the repository at this point in the history
My kuku Milestone 10 : Eggs resource
  • Loading branch information
Nemwel-Boniface authored Dec 12, 2024
2 parents 4c92dd7 + 0e7346a commit 00b6c72
Show file tree
Hide file tree
Showing 21 changed files with 367 additions and 61 deletions.
Binary file added app/assets/images/malegradpic1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/turkey.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions app/assets/stylesheets/eggs/eggs_home.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* Eggs Index Page Styles */
.eggs {
padding: 2rem;
}

.newEggLink {
text-align: center;
margin-bottom: 2rem;
}

.newEggLink .btn {
background-color: #28a745;
color: #fff;
padding: 0.5rem 1rem;
border-radius: 5px;
text-decoration: none;
}

.newEggLink .btn:hover {
background-color: #218838;
}

.eggStatsWrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}

.card {
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 1.5rem;
text-align: center;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.card h3 {
font-size: 1.5rem;
margin-bottom: 1rem;
color: #495057;
}

.card p {
font-size: 1.25rem;
color: #6c757d;
}
26 changes: 14 additions & 12 deletions app/controllers/chickens_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def create

respond_to do |format|
if @chicken.save
format.html { redirect_to chicken_url(@chicken), notice: 'Chicken was successfully created.' }
format.html { redirect_to chickens_path, notice: 'Poultry was successfully created.' }
format.json { render :show, status: :created, location: @chicken }
else
format.html { render :new, status: :unprocessable_entity }
Expand All @@ -35,15 +35,17 @@ def create
end

# PATCH/PUT /chickens/1 or /chickens/1.json

def update
respond_to do |format|
if @chicken.update(chicken_params)
format.html { redirect_to chicken_url(@chicken), notice: 'Chicken was successfully updated.' }
format.json { render :show, status: :ok, location: @chicken }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @chicken.errors, status: :unprocessable_entity }
end
additional_poultry = params[:chicken][:no_of_poultry].to_i
@chicken.no_of_poultry += additional_poultry

if @chicken.save
flash[:notice] = "#{additional_poultry} more #{@chicken.poultry_type.pluralize} added successfully."
redirect_to chickens_path
else
flash[:alert] = 'There was an error updating the poultry.'
render :edit
end
end

Expand All @@ -52,7 +54,7 @@ def destroy
@chicken.destroy

respond_to do |format|
format.html { redirect_to chickens_url, notice: 'Chicken was successfully destroyed.' }
format.html { redirect_to chickens_url, notice: 'Poultry was successfully destroyed.' }
format.json { head :no_content }
end
end
Expand All @@ -66,7 +68,7 @@ def set_chicken

# Only allow a list of trusted parameters through.
def chicken_params
params.require(:chicken).permit(:tag_number, :age, :date_hatched, :parent_id, :user_id, :chicken_image,
:poultry_type)
params.require(:chicken).permit(:no_of_poultry, :age, :date_hatched, :parent_id, :user_id, :chicken_image,
:poultry_type, :price_per_poultry)
end
end
51 changes: 51 additions & 0 deletions app/controllers/eggs_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
class EggsController < ApplicationController
# List all eggs and stats (index remains unchanged)
def index
@eggs = Egg.all
@egg_stats = Egg.total_eggs_and_prices
end

# Display the form for creating a new egg record
def new
@egg = Egg.new
end

# Create a new egg record
def create
@egg = Egg.new(egg_params)
if @egg.save
redirect_to eggs_path, notice: 'Egg was successfully recorded.'
else
render :new
end
end

# Display the form for editing an existing egg record
def edit
@egg = Egg.find(params[:id])
end

# Update an existing egg record
def update
@egg = Egg.find(params[:id])
if @egg.update(egg_params)
redirect_to eggs_path, notice: 'Egg was successfully updated.'
else
render :edit
end
end

# Delete an egg record
def destroy
@egg = Egg.find(params[:id])
@egg.destroy
redirect_to eggs_path, notice: 'Egg was successfully deleted.'
end

private

# Strong parameters for egg attributes
def egg_params
params.require(:egg).permit(:egg_count, :egg_size, :poultry_type, :laid_on, :price_per_egg)
end
end
2 changes: 2 additions & 0 deletions app/helpers/eggs_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module EggsHelper
end
53 changes: 34 additions & 19 deletions app/models/chicken.rb
Original file line number Diff line number Diff line change
@@ -1,42 +1,45 @@
class Chicken < ApplicationRecord
# Custom slug config here
extend FriendlyId
friendly_id :tag_number, use: :slugged
friendly_id :poultry_type, use: :slugged

def to_param
slug
end

POULTRY_TYPES = %w[Chicken Duck Goose Turkey Quail].freeze
# Enums with string values
enum poultry_type: {
chicken: 'chicken',
duck: 'duck',
goose: 'goose',
turkey: 'turkey',
quail: 'quail'
}, _prefix: true

validates :poultry_type, presence: true, inclusion: { in: POULTRY_TYPES }
validates :poultry_type, presence: true, inclusion: { in: poultry_types.keys }
validates :no_of_poultry, numericality: { greater_than: 0 }

# Associations
belongs_to :user
has_one_attached :chicken_image
has_many :eggs, dependent: :destroy

# Callback for custom methods
before_create :generate_tag_number
before_create :calculate_age
before_create :set_price_per_poultry

private

def generate_tag_number
# Get the corrent month eh June
current_month = Date.today.strftime('%B')

# Get the current date in the month
current_date = Date.today.strftime('%d')

id = Chicken.count + 1

# Let's append a few zeros before the ID of the record being created
tag_number_with_zeros = format('%03d', id)
# Calculate total price for all poultry
def total_price
no_of_poultry * price_per_poultry
end

# Now let's wire them all up together
self.tag_number = "#{current_month}#{current_date}#{tag_number_with_zeros}"
# Calculate price for a specific poultry type (e.g., Chicken, Duck, etc.)
def self.price_by_type(type)
where(poultry_type: type).sum(:price_per_poultry)
end

private

def calculate_age
if date_hatched.present?
days_old = (Date.today - date_hatched.to_date).to_i
Expand All @@ -46,4 +49,16 @@ def calculate_age
self.age = nil
end
end

# Set the price per poultry based on the poultry_type
def set_price_per_poultry
self.price_per_poultry = case poultry_type
when 'chicken' then 100.0
when 'duck' then 120.0
when 'goose' then 150.0
when 'turkey' then 200.0
when 'quail' then 80.0
else 0.0
end
end
end
28 changes: 28 additions & 0 deletions app/models/egg.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class Egg < ApplicationRecord
# Enums
EGG_SIZE = %w[Small Medium Large].freeze
POULTRY_TYPES = %w[Chicken Duck Goose Turkey Quail].freeze

# Validations
validates :poultry_type, presence: true, inclusion: { in: POULTRY_TYPES }
validates :egg_size, presence: true, inclusion: { in: EGG_SIZE }
validates :egg_count, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :price_per_egg, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :laid_on, presence: true

# Methods to calculate statistics
def self.total_eggs_and_prices
POULTRY_TYPES.each_with_object({}) do |poultry_type, stats|
eggs = where(poultry_type:)
total_eggs = eggs.sum(:egg_count)
total_price = eggs.sum('egg_count * price_per_egg')
average_price_per_egg = eggs.average(:price_per_egg)

stats[poultry_type] = {
total_eggs:,
total_price:,
average_price_per_egg:
}
end
end
end
30 changes: 23 additions & 7 deletions app/views/chickens/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
<h1>Editing chicken</h1>
<p style="color: green"><%= notice %></p>

<%= render "form", chicken: @chicken %>
<header class="aboutheader">
<h2>Edit Poultry</h2>
<h3><%= link_to "Home", root_path %> <span>-</span>Poultry</h3>
</header>

<br>
<main class="edit-chicken">
<h2 class="darkgreentext">Add More to Your Poultry Inventory</h2>

<div>
<%= link_to "Show this chicken", @chicken %> |
<%= link_to "Back to chickens", chickens_path %>
</div>
<%= form_with(model: @chicken, url: chicken_path(@chicken), method: :patch, local: true) do |form| %>
<div>
<strong>Poultry Type:</strong>
<p><%= @chicken.poultry_type.capitalize %></p>
</div>

<div>
<%= form.label :no_of_poultry, "Number of additional Poultry:" %>
<%= form.number_field :no_of_poultry, min: 1, value: 1 %>
</div>

<div>
<%= form.submit "Update Poultry Inventory" %>
</div>
<% end %>
</main>
23 changes: 16 additions & 7 deletions app/views/chickens/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,32 @@

<div>
<p>
<strong>Tag number:</strong>
<%= chicken.tag_number %>
<strong>Poultry type:</strong>
<%= chicken.poultry_type.capitalize %>
</p>

<p>
<strong>Poultry type:</strong>
<%= chicken.poultry_type %>
<strong>Number of Poultry:</strong>
<%= chicken.no_of_poultry %>
</p>

<p>
<strong>Price per Poultry:</strong>
<%= chicken.price_per_poultry %>
</p>

<p>
<strong>Total price of Poultry:</strong>
KES <%= chicken.total_price %>0
</p>

<p class="chickenlink">
<%= link_to "CHICKEN DETAILS", chicken %>
<%= link_to "Add more #{chicken.poultry_type.capitalize}", edit_chicken_path(chicken) %>
<i class="fa fa-arrow-right" aria-hidden="true"></i>
</p>
</div>
</div>
<% end %>
<% end %>
</section>

</main>
</main>
20 changes: 7 additions & 13 deletions app/views/chickens/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

<section class="signup">
<div class="signupleft">

<%= image_tag("freerangehens.jpg", alt: "Image of chicken in a farm") %>
</div>

Expand All @@ -22,17 +21,18 @@
<% end %>

<div class="signupinput">
<%= form.text_field :tag_number, placeholder: "Tag Number", type: :hidden %>
<%= form.number_field :no_of_poultry, placeholder: "Number of poultry", min: 1 %>
</div>

<div class="signupinput">
<%= form.label :chicken_image %>
<%= form.file_field :chicken_image %>
<div id="image-preview"></div>
<%= form.label :poultry_type, "Select Poultry Type" %>
<%= form.select :poultry_type, Chicken.poultry_types.map { |type, price| ["#{type.capitalize} - $#{price}", type] }, prompt: "Choose a poultry type" %>
</div>

<div class="signupinput">
<%= form.number_field :age, type: :hidden, placeholder: "Age in weeks" %>
<%= form.label :chicken_image %>
<%= form.file_field :chicken_image %>
<div id="image-preview"></div>
</div>

<div class="signupinput">
Expand All @@ -45,16 +45,10 @@
<%= form.text_field :parent_id, placeholder: "Parent ID" %>
</div>

<div class="signupinput">
<%= form.label :poultry_type, "Select Poultry Type" %>
<%= form.select :poultry_type, options_for_select(Chicken::POULTRY_TYPES), prompt: "Choose a poultry type" %>
</div>


<%= form.hidden_field :user_id, value: current_user.id %>

<div class="devisesubmit">
<%= form.submit "Add Chicken" %>
<%= form.submit "Add Poultry" %>
</div>
<% end %>
</div>
Expand Down
Loading

0 comments on commit 00b6c72

Please sign in to comment.