Fungsi Generate Code
Product mempunyai attribut code dan codenya nanti akan di generate secara otomatis.Attribut ini nantinya bisa digunakan untuk barcode.
- Pada folder view/productIndex dan formnya dirubah
- File _form.html.erb bagian user dan codenya di hilangkan
- Untuk index.html.erb codenya seperti berikut
- Tambahkan code pada model product
- Selanjutnya di controller productnya tambahkan baris berikut pada method create
- Lakukan input data di url http://localhost:3000/products/new
<%= form_for(@product) do |f| %>
<% if @product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% @product.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :price %><br>
<%= f.text_field :price %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<h1>Listing Product</h1>
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Code</th>
<th>Price</th>
<th></th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= product.code %></td>
<td><%= product.price %></td>
<td><%= link_to 'Show', product %></td>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td>
<%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Product', new_product_path %>
before_create :set_code
def generate_code(size = 6)
charset = %w{ 2 3 4 6 7 9 A C D E F G H J K M N P Q R T V W X Y Z}
(0...size).map{ charset.to_a[rand(charset.size)] }.join
end
def set_code
self.code = generate_code(6)
end
@product = Product.new(product_params)
@product.user_id = current_user.id #tambahkan code ini setelah code diatas
Membuat Nested Form
- Edit model sale.rb tambahkan code berikut
- Edit partial _form.html.erb di dalam folder view/sales
- Edit aplication_helper.rb tambahkan code berikut
- buat file partial _item_fields.html.erb di folder sales/app/views/sales/ isinya seperti berikut
- Periksa di http://localhost:3000/sales/new hasilnya akan seperti gambar berikut
has_many :items
accepts_nested_attributes_for :items, allow_destroy: true
<%= form_for(@sale) do |f| %>
<% if @sale.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@sale.errors.count, "error") %> prohibited this sale from being saved:</h2>
<ul>
<% @sale.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<%= f.fields_for :items do |builder| %>
<%= render 'item_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Item", f, :items %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<script type="text/javascript">
jQuery(function() {
$('form').on('click', '.remove_fields', function(event) {
$(this).prev('input[type=hidden]').val('1');
$(this).closest('fieldset').hide();
return event.preventDefault();
});
return $('form').on('click', '.add_fields', function(event) {
var regexp, time;
time = new Date().getTime();
regexp = new RegExp($(this).data('id'), 'g');
$(this).before($(this).data('fields').replace(regexp, time));
return event.preventDefault();
});
});
</script>
def link_to_add_fields(name, f, association)
new_object = f.object.send(association).klass.new
id = new_object.object_id
fields = f.fields_for(association, new_object, child_index: id) do |builder|
render(association.to_s.singularize + "_fields", f: builder)
end
link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
end
<fieldset>
<%= f.label :product, "Product" %>
<%= f.collection_select :product_id, Product.all, :id, :name %>
<%= f.label :quantity, "Quantity" %>
<%= f.text_field :quantity, class: 'padli' %>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "remove_fields" %>
</fieldset>
Fungsi Hitung Penjualan
Tadikan di form penjualan kita sudah bisa input item dan jumlahnya, tapi total penjualanya belum terhitung. Nah sekarang kita akan buat menghitung total nya:- Edit model item ketikan code berikut:
- Edit model sale untuk menghitung total harga penjualan berikut codenya
- Edit controllers sales_controller.rb
- Tambahkan pada method create code berikut
- Tambahkan parameter yang akan di permit
- Lakukan input data penjualan http://localhost:3000/sales/new tambahkan beberapa item kemudian simpan
- Periksa apakah total penjualanya terhitung
- Edit file show di folder view sale
before_save :set_total
def set_total
if self.quantity.blank?
0
else
self.total = self.quantity * self.product.price
end
end
def subtotal
if self.quantity.blank?
0
else
self.quantity * self.product.price
end
end
def subtotals
self.items.map { |i| i.subtotal }
end
def total_all
subtotals.sum
end
@sale = Sale.new(sale_params)
@sale.user_id = current_user.id #tambahkan ini setelah code di atas
@sale.total = @sale.total_all #tambahkan ini setelah code di atas
params.require(:sale).permit(:name, items_attributes: [:id,:product_id, :price,:quantity,:total,:_destroy])
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @sale.name %>
</p>
<%= link_to 'Edit', edit_sale_path(@sale) %> |
<%= link_to 'Back', sales_path %>
<h1>Listing Item</h1>
<table class="table table-striped">
<thead>
<tr>
<th>Product</th>
<th>price</th>
<th>quantity</th>
<th>total</th>
<th></th>
</tr>
</thead>
<tbody>
<% @sale.items.each do |item| %>
<tr>
<td><%= item.product.name %></td>
<td><%= item.product.price %></td>
<td><%= item.quantity %></td>
<td><%= item.total %></td>
</tr>
<% end %>
</tbody>
</table>
<hr>
<p> Total </p>
<%= @sale.total%>
<hr>
Mengatur User-Roles
Pada bagian ini kita akan mengatur hak akses user pada aplikasi POS.- Generate cancan
- Tambahkan code di class ability.rb seperti berikut:
- Edit products_controller tambahkan load and authorize seperti berikut
- Edit sales_controller tambahkan load and authorize seperti berikut
- Edit aplication_controller tambahkan baris code berikut
- Untuk link tinggal di kasih kondisi seperti berikut
$ rails g cancan:ability
class Ability
include CanCan::Ability
def initialize(user)
if user.present?
if user.role.name == 'admin'
can :manage, :all
else
can :create , Product
can :create , Sale
can :read, :all
end
else
can :read, :all
end
end
end
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
load_and_authorize_resource
# GET /products
# GET /products.json
def index
@products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
@product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
@product = Product.new(product_params)
@product.user_id = current_user.id #tambahkan code ini setelah code diatas
respond_to do |format|
if @product.save
format.html { redirect_to @product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: @product }
else
format.html { render :new }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: @product }
else
format.html { render :edit }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
@product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
@product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:code, :name, :price, :user_id)
end
end
class SalesController < ApplicationController
before_action :set_sale, only: [:show, :edit, :update, :destroy]
load_and_authorize_resource
# GET /sales
# GET /sales.json
def index
@sales = Sale.all
end
# GET /sales/1
# GET /sales/1.json
def show
end
# GET /sales/new
def new
@sale = Sale.new
end
# GET /sales/1/edit
def edit
end
# POST /sales
# POST /sales.json
def create
@sale = Sale.new(sale_params)
@sale.user_id = current_user.id #tambahkan ini setelah code di atas
@sale.total = @sale.total_all #tambahkan ini setelah code di atas
respond_to do |format|
if @sale.save
format.html { redirect_to @sale, notice: 'Sale was successfully created.' }
format.json { render :show, status: :created, location: @sale }
else
format.html { render :new }
format.json { render json: @sale.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /sales/1
# PATCH/PUT /sales/1.json
def update
respond_to do |format|
if @sale.update(sale_params)
format.html { redirect_to @sale, notice: 'Sale was successfully updated.' }
format.json { render :show, status: :ok, location: @sale }
else
format.html { render :edit }
format.json { render json: @sale.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sales/1
# DELETE /sales/1.json
def destroy
@sale.destroy
respond_to do |format|
format.html { redirect_to sales_url, notice: 'Sale was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_sale
@sale = Sale.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def sale_params
params.require(:sale).permit(:name, items_attributes: [:id,:product_id, :price,:quantity,:total,:_destroy])
end
end
rescue_from CanCan::AccessDenied do |exception|
flash[:error] = "Access denied."
redirect_to root_url
end
<td><%= link_to 'Show', sale %></td>
<% if can? :update, Sale %>
<td><%= link_to 'Edit', edit_sale_path(sale) %></td>
<%end%>
<% if can? :destroy, Sale %>
<td><%= link_to 'Destroy', sale, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
Public Activities
Fitur ini bertujuan untuk mencatat aktifitas user pada aplikasi. Sehingga apabila ada karyawan yang melakukan aktifitas pelanggaran / kecurangan, sistem admin bisa melihat bukti aktifitasnya.- Generate public_activity
- Di aplication_controller.rb tambahkan code
- Di model product.rb dan sale.rb tambahkan code berikut
- Buat controller untuk activities
- Di routesnya tambahkan code
- Di controllernya tambahkan code berikut
- Di viewnya buat file index.html.erb di folder activities isi dengan code berikut
- Buat folder public_activity di view
- Di dalam folder public_activity buat folder product dan sale
- Di dalam folder product dan sale buat file html partial _create.html.erb ,_update.html.erb, _destroy.html.erb
- Create.html.erb codenya seperti berikut
- _update.html.erb
- _destroy.html.erb
- Masuk folder layout dan edit file application.html.erb tambahkan code dibawah class nav navbar-nav
- Terakhir lakukan proses insert, update dan delete di http://localhost:3000/sales dan http://localhost:3000/products
- Hasilnya bisa di akses di http://localhost:3000/activities
$ rails g public_activity:migration
$ rake db:migrate
include PublicActivity::StoreController
include PublicActivity::Model
tracked owner: ->(controller, model) { controller && controller.current_user}
$ rails g controller activities
root to: 'home#index'
resources :activities
class ActivitiesController < ApplicationController
def index
@activities = PublicActivity::Activity.order("created_at desc")
end
end
<h1>Listing Activities</h1>
<table class="table table-striped table-bordered table-condensed sortable">
<thead>
<tr>
<th><%= "Activities"%></th>
</tr>
</thead>
<tbody>
<% @activities.each do |activity| %>
<tr>
<td valign="top">
<%= activity.owner.email %>
<%= render_activity activity %>
</td>
</tr>
<% end %>
</tbody>
<tfoot>
<tr>
<td colspan="3"></td>
</tr>
</tfoot>
</table>
added product
<% if activity.trackable %>
<%= link_to activity.trackable.name, product_path(activity.trackable.id) %>
<% else %>
which has since been removed
<% end %>
Updated product
<% if activity.trackable %>
<%= link_to activity.trackable.name, product_path(activity.trackable.id) %>
<% else %>
which has since been removed
<% end %>
removed a produc
·<li><%= link_to "All Activities", activities_path %></li>