Friends, I have a form that uses nested_attributes and I use the cocoon gem. I have 3 models involved. Variation that contains the stock, Order, which contains the order and is the Detail parent that contains the order detail.
The save is working correctly, however I need to update each item's stock before saving.
Fields:
Details:
t.string "order_id"
t.string "cod_produto"
t.string "desc_produto"
t.string "cod_cor"
t.string "desc_cor"
t.string "desc_tamanho"
t.decimal "preco"
t.integer "quantidade"
t.datetime "created_at"
t.datetime "updated_at"
t.float "total"
Orders:
t.string "customer_id"
t.decimal "valor_total"
t.integer "item_total"
t.string "order_num"
t.datetime "created_at"
t.datetime "updated_at"
Variations:
create_table "variations", force: true do |t|
t.string "product_id"
t.string "size_id"
t.string "color_id"
t.integer "quantity"
t.string "barcode"
t.datetime "created_at"
t.datetime "updated_at"
do
The templates are:
order.rb
class Order < ActiveRecord::Base
has_many :details, dependent: :destroy
belongs_to :customer
accepts_nested_attributes_for :details, reject_if: proc { |attributes| attributes['cod_produto'].blank? }, :allow_destroy => true
validates :customer_id, :presence => true
after_validation :sum_details
after_create :set_order_num
private
def set_order_num
update(order_num: "#{Date.current.year}-#{self.id}")
end
def sum_details
total = 0
qtd = 0
self.details.each do |d|
total += (d.quantidade * d.preco) if d.quantidade.present?
qtd += d.quantidade if d.quantidade.present?
end
self.valor_total = total
self.item_total = qtd
end
end
detail.rb
class Detail < ActiveRecord::Base
belongs_to :order
after_validation :update_quantity
before_save :get_quantity
private
def get_quantity
@qtd = self.quantidade
end
def update_quantity
if self.quantidade > 0
self.quantidade = self.quantidade - @qtd
end
end
end
What I need to do is: before saving the detail model (remembering that it is a child form of the order model), I need to find the quantity of a product that is in the variations model and update its quantity. For this you have to take the model detail the product_code + cod_cor + desc_tamanho and look for the barcode field in the variation model to update your inventory. I'm using before_save to try to get the quantity but neither is it working ... Could anyone give some light?
Thank you
EDIT: Inclusion of controllers:
orders_controller.rb
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
require "json"
def consulta_produto
@variacao = Variation.find_by(barcode:params[:barcode])
if @variacao.present?
hash = {:cod_produto => @variacao.product.cod ,:desc_produto => @variacao.product.descricao,:cod_cor => @variacao.color.cod, :desc_cor => @variacao.color.descricao,:desc_tamanho => @variacao.size.descricao,:preco => @variacao.product.price }
render :json => { :resultado => hash }
else
render :json => {:resultado => "error"}
end
end
# GET /orders
# GET /orders.json
def index
@orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
@order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
@order = Order.new(order_params)
respond_to do |format|
if @order.save
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: @order }
else
format.html { render :new }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if @order.update(order_params)
format.html { redirect_to @order, notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:customer_id, :valor_total, :item_total, :order_num, details_attributes: [:id,:order_id, :cod_produto, :desc_produto, :cod_cor, :desc_cor, :desc_tamanho,:preco,:quantidade,:total, :_destroy])
end
end
details_controller.rb
before_action :set_detail, only: [:show, :edit, :update, :destroy]
# GET /details
# GET /details.json
def index
@details = Detail.all
end
# GET /details/1
# GET /details/1.json
def show
end
# GET /details/new
def new
@detail = Detail.new
end
# GET /details/1/edit
def edit
end
# POST /details
# POST /details.json
def create
@detail = Detail.new(detail_params)
respond_to do |format|
if @detail.save
format.html { redirect_to @detail, notice: 'Detail was successfully created.' }
format.json { render :show, status: :created, location: @detail }
else
format.html { render :new }
format.json { render json: @detail.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /details/1
# PATCH/PUT /details/1.json
def update
respond_to do |format|
if @detail.update(detail_params)
format.html { redirect_to @detail, notice: 'Detail was successfully updated.' }
format.json { render :show, status: :ok, location: @detail }
else
format.html { render :edit }
format.json { render json: @detail.errors, status: :unprocessable_entity }
end
end
end
# DELETE /details/1
# DELETE /details/1.json
def destroy
@detail.destroy
respond_to do |format|
format.html { redirect_to details_url, notice: 'Detail was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_detail
@detail = Detail.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def detail_params
params.require(:detail).permit(:order_id, :cod_produto, :desc_produto, :cod_cor, :desc_cor, :desc_tamanho, :preco, :quantidade)
end
variations_controller.rb
class VariationsController < ApplicationController
before_action :set_variation, only: [:show, :edit, :update, :destroy]
# require 'barby/outputter/cairo_outputter'
# def barcode_output( order )
# barcode_string = order.barcode
# barcode = Barby::Code128B.new(barcode_string)
# # PNG OUTPUT
# data = barcode.to_image(height: 15, margin: 5).to_data_url
# end
# GET /variations
# GET /variations.json
def export
@data = Variation.order(:created_at)
# @data = Variation.select(:barcode).order(created_at: :desc)
respond_to do |format|
format.html { redirect_to root_url }
format.csv { send_data @data.to_csv }
end
end
def index
# @barcode = Barby::Code128B.new("160P10") rescue nil
# @outputter = Barby::HtmlOutputter.new(@barcode)
# @blob = Barby::PngOutputter.new(@barcode).to_png #Raw PNG data
# @barcode = Barby::HtmlOutputter.new('160P10')
# @barcode_for_html = Barby::HtmlOutputter.new(@barcode)
@variations = Variation.all
# @import = Variation::Import.new
respond_to do |format|
format.html
format.csv { send_data @variations}
end
# def import
# @import = Variation::Import.new variation_import_params
# if @import.save
# redirect_to variations_path, notice: "Importados #{@import.imported_count} Cod Barras"
# else
# @variations = Variation.all
# flash[:alert] = "Foram encontrados #{@import.errors.count} erros no CSV"
# render action: index
# end
# end
# require 'barby/outputter/png_outputter'
# blob = Barby::PngOutputter.new("12345").to_png #Raw PNG data
# File.open('barcode.png', 'wb'){|f| f.write blob }
#Convenience method
# File.open('barcode2.png', 'wb'){|f| f.write barcode.to_png }
# @barcode = Barby::EAN13.new('000000000')
# @barcode_for_html = Barby::CairoOutputter.new("0123456789")
# Variation.new.barcode # => Barby::Code39 object
# Variation.new.barcode_data # => <Barby::Code39 object>.to_png
end
# GET /variations/1
# GET /variations/1.json
def show
end
# GET /variations/new
def new
@variation = Variation.new
# @variacoes_js = Variation.joins(:color, :product, :size).includes(:color, :product, :size)
# # ActiveRecord::Base.include_root_in_json = true
# gon.variacoes = @variacoes_js.to_json
# @tamanhos = Size.order(:descricao).select(:id,:descricao)
# gon.tamanhos = @tamanhos.to_json
# @produtos = Product.order(:cod).select(:cod,:descricao)
# gon.produtos = @produtos.to_json
end
# GET /variations/1/edit
def edit
end
# POST /variations
# POST /variations.json
def create
@variation = Variation.new(variation_params)
respond_to do |format|
if @variation.save
format.html { redirect_to variations_path, notice: 'Variation was successfully created.' }
format.json { render :index, status: :created, location: @variation }
else
format.html { render :new }
format.json { render json: @variation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /variations/1
# PATCH/PUT /variations/1.json
def update
respond_to do |format|
if @variation.update(variation_params)
format.html { redirect_to @variation, notice: 'Variation was successfully updated.' }
format.json { render :show, status: :ok, location: @variation }
else
format.html { render :edit }
format.json { render json: @variation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /variations/1
# DELETE /variations/1.json
def destroy
@variation.destroy
respond_to do |format|
format.html { redirect_to variations_url, notice: 'Variation was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_variation
@variation = Variation.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def variation_params
params.require(:variation).permit(:product_id, :size_id, :color_id, :quantity, :barcode)
end
def variation_import_params
params.require(:variation_import).permit(:file)
end
end