Добавление записи о приёме товара.
Для этого необходимо нажать по ссылке «Приём товара на склад»
Откроется вот такое окно:
Тут необходимо указать поставщика из списка доступных поставщиков. Затем заполнить «примечание» если необходимо. А так же указать ряд пар «товар - количество».
Система обладает защитой от некорректного ввода. Если что-то введено неправильно и оператор попытался сохранить запись, то система выдаст предупреждение.
После исправления ошибок оператор снова нажимает «создать» и, если на этот раз всё хорошо, то запись о поступлении товара на склад сохранится. Теперь на главной странице приложения в таблице «Состояние склада» появятся поступившие товары (а если они были и раньше, то обновится их количество).
Отправка товара со склада
Для отправки товара в магазин необходимо на главной странице приложения нажать на ссылку «Отправка товара в магазин».
В открывшемся окне будет необходимо указать магазин и ряд пар «товар - количество», которые мы отправляем в данный магазин.
Тут так же есть защита от некорректного ввода. И в случае попытки отправить товар, которого нету на складе или слишком большое количество товара, система выдаст предупреждение.
После исправления ошибок система сохранит информацию об отправке товара. И на главной странице изменится количество товаров.
Управление магазинами
Для перехода в секцию управления магазинами надо кликнуть по ссылке «Магазины» вверху любой страницы приложения.
На открывшемся экране мы увидим список имеющихся магазинов со ссылками для изменения, удаления или просмотра подробных сведений о магазине.
Управление поставщиками
Аналогично, как и в случае с магазинами, необходимо в верхнем блоке навигации кликнуть на ссылку «Поставщики товара»
Управление товарами
Аналогично, как и в случае с магазинами, необходимо в верхнем блоке навигации кликнуть на ссылку «Товары, с которыми ведётся работа».
Тут можно отредактировать, удалить имеющиеся товары или добавить новые.
Заключение
Я изучил и на практике закрепил работу с базами данных, написав приложение по управлению работой склада. Если бы это приложение делалось не в учебных целях, а в практических, то можно было бы добавить ещё ряд функций. Например, вести учёт денежных расчетов за товар. Можно было бы сразу и вычислять прибыль склада. И даже зарплату сотрудникам склада. К слову, на работе мне довелось поработать, а сейчас и поддерживать, приложение которое организует работу юридической компании с клиентами. А так же ведёт полный финансовый учёт и расчет зарплаты сотрудникам на основе проделанной ими работы. Это один из тех примеров, когда ведение бухгалтерии организовано не через бумажную волокиту, а напрямую через взаимодействие приложения с базой данных.
Список использованных источников
-
Agile Web Development with Rails, 3rd edition, Sam Ruby, Dave Thomas, David Heinemeier Hansson, 2009, 792 c
-
Programming Ruby 1.9 (3rd edition), Dave Thomas, with Chad Fowler and Andy Hunt, 2009, 944с
-
http://guides.rubyonrails.com
-
http://apidock.com
Приложение 1. Схема базы данных
Приложение 2. Листинг основных классов приложения
class Product < ActiveRecord::Base
attr_accessible :sku, :name, :description
has_many :line_items, :dependent => :destroy
validates_presence_of :sku, :name
validates_uniqueness_of :sku
validates_numericality_of :quantity, :greater_than_or_equal_to => 0
end
class Order < ActiveRecord::Base
attr_accessible :store_id, :line_items_attributes
belongs_to :store
has_many :line_items, :as => :object, :dependent => :destroy
accepts_nested_attributes_for :line_items, :reject_if => proc {|attrs| attrs['product_id'].blank?}
has_many :products, :through => :line_items
validates_presence_of :store
end
class Store < ActiveRecord::Base
attr_accessible :name, :address, :description
has_many :orders, :dependent => :nullify
validates_presence_of :name
end
class Supply < ActiveRecord::Base
attr_accessible :supplier_id, :description, :line_items_attributes
belongs_to :supplier
has_many :line_items, :as => :object, :dependent => :destroy
accepts_nested_attributes_for :line_items, :reject_if => proc {|attrs| attrs['product_id'].blank?}
has_many :products, :through => :line_items
validates_presence_of :supplier
end
class Supplier < ActiveRecord::Base
attr_accessible :name, :phone, :description
has_many :supplies, :dependent => :nullify
validates_presence_of :name
end
class LineItem < ActiveRecord::Base
attr_accessible :object_id, :object_type, :product_id, :quantity
belongs_to :product
belongs_to :object, :polymorphic => true
validates_presence_of :product_id
validates_numericality_of :quantity, :greater_than => 0
validates_each :quantity do |record, attr, value|
if record.object_type == 'Order'
record.errors.add attr, "не должно превышать общее количество продукта на складе (#{record.product.quantity})" if value > record.product.quantity
end
end
after_create :update_product_quantity
def update_product_quantity
case object.class.name
when 'Supply'
product.update_attribute(:quantity, product.quantity + quantity)
when 'Order'
product.update_attribute(:quantity, product.quantity - quantity)
end
end
end
class WelcomeController < ApplicationController
def index
@products_in_stock = Product.where("quantity > 0").order(:name)
last_orders = Order.order('created_at DESC').limit(10)
last_supplies = Supply.order('created_at DESC').limit(10)
@last_operations = (last_orders + last_supplies).sort {|a, b| b.created_at <=> a.created_at}.shift(10)
end
end
class OrdersController < ApplicationController
def index
@orders = Order.order('created_at DESC')
end
def show
@order = Order.find(params[:id])
end
def new
@order = Order.new
end
def create
@order = Order.new(params[:order])
if @order.save
flash[:notice] = "Запись об отправке товара сохранена"
redirect_to root_path
else
render :action => 'new'
end
end
end
class ProductsController < ApplicationController
def index
@products = Product.order(:name)
end
def show
@product = Product.find(params[:id])
end
def new
@product = Product.new
end
def create
@product = Product.new(params[:product])
if @product.save
flash[:notice] = "Продукт добавлен"
redirect_to @product
else
render :action => 'new'
end
end
def edit
@product = Product.find(params[:id])
end
def update
@product = Product.find(params[:id])
if @product.update_attributes(params[:product])
flash[:notice] = "Продукт обновлён"
redirect_to @product
else
render :action => 'edit'
end
end
def destroy
@product = Product.find(params[:id])
@product.destroy
flash[:notice] = "Продукт удалён"
redirect_to products_url
end
end