Check stock of an inventory product with Ruby on Rails

0

I have a small inventory system ready which works perfectly, however, I have not been able to get it to check the availability of a product at the time of making a sale, although on the one hand it is checking if there are stocks, and on the other hand check that the sale amount is adjusted to the amount of stocks available, I think I understand, I think this could be achieved with ajax although I do not have a clear idea or a validation with conditions, I would appreciate it give me a hand, my code is this:

Migration of the Products table

class CreateProducts < ActiveRecord::Migration[5.2]
  def change
    create_table :products do |t|
      t.string :code
      t.string :name
      t.float :price
      t.integer :weight
      t.string :unity
      t.float :utility

      t.timestamps
    end
  end
end

Migrating the Inventory Transactions table

class CreateInventoryTransactions < ActiveRecord::Migration[5.2]
  def change
    create_table :inventory_transactions do |t|
      t.string :invoice
      t.integer :product_id
      t.string :provider
      t.integer :quantity
      t.boolean :transaction_type

      t.timestamps
    end
  end
end

Product Model

class Product < ApplicationRecord

    validates :code, :name, :price, :utility, :weight, :unity, presence: true
    validates :code, uniqueness: true

    has_many :inventory_transactions

    def quantity
        self.inventory_transactions.where(transaction_type: false).pluck(:quantity).sum - self.inventory_transactions.where(transaction_type: true).pluck(:quantity).sum
    end    

    def subtotal
        self.price * quantity
    end

    def profit
        subtotal * self.utility / 100
    end

    def iva
        (subtotal + profit) * 0.13
    end

    def total
        subtotal + profit + iva
    end

end

InventoryTransaction model

class InventoryTransaction < ApplicationRecord

    belongs_to :product

    def ganancia
        self.inventory_transactions.pluck(:utility)
    end 

end

Purchase / Sale Form

<%= form_with(model: inventory_transaction, local: true) do |form| %>
  <% if inventory_transaction.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(inventory_transaction.errors.count, "error") %> prohibited this inventory_transaction from being saved:</h2>

      <ul>
      <% inventory_transaction.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :factura %>
    <%= form.text_field :invoice %>
  </div>

  <div class="field">
    <%= form.label :proveedor %>
    <%= form.text_field :provider %>
  </div>

  <div class="field">
    <%= form.label :id_del_product %>
    <%= form.number_field :product_id %>
  </div>

  <div class="field">
    <%= form.label :quantity %>
    <%= form.number_field :quantity %>
  </div>

  <div class="field">
    <%= form.label :transaction_type %> <!-- Determina el tipo de transaccion en el inventario -->
    <%= form.select(:transaction_type, [['Compra', false], ['Venta', true]], { :include_blank => "Tipo de transacción" }, required: true, class: "input-group-field") %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

In conclusion, from the transaction form, when making a sale-type transaction, you must check in stock, that is, by means of the quantity method found in the Product model , you must determine if the amount of sale is not greater than the availability of stocks in inventory, I greatly appreciate your help, greetings!

    
asked by Hector Hernandez 30.06.2018 в 08:31
source

1 answer

0

One way to achieve this is to add a method in your model InventoryTransaction and use it through a validation; for example:

# app/models/inventory_transaction.rb

class InventoryTransaction < ApplicationRecord
  belongs_to :product

  validate :product_quantity_available

  def ganancia
    self.inventory_transactions.pluck(:utility)
  end

  private
  def product_quantity_available
    if quantity > product.quantity
      errors.add(:base, 'Quantity not available')
    end
  end
end

In summary, you are validating in your model that the amount is correct before saving it, just as you would with any other attribute; the difference is that the comparison value is obtained from another model (for that we use product.quantity ).

Now, as it is a validation of your model, the error 1 'Quantity not available' will be shown in your view if the amount is greater than the one you have.

1 :base allows you to add an error message without the need to assign it to an attribute of the model.

    
answered by 01.07.2018 в 04:17