adding stock resume

This commit is contained in:
Philippe 2021-11-18 17:47:00 +01:00
parent b2b85f77dd
commit 8f89898817
26 changed files with 604 additions and 68 deletions

View File

@ -106,9 +106,9 @@ group :development do
gem 'capistrano-bundler', '~> 1.1', require: false
gem "capistrano-rvm", group: :development
gem 'capistrano3-nginx', '~> 2.0', group: :development
gem "awesome_print"
gem 'table_print', '~> 1.5', '>= 1.5.7'
end
gem "awesome_print"
gem 'zip-zip'

View File

@ -319,6 +319,7 @@ GEM
sshkit (1.20.0)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
table_print (1.5.7)
temple (0.8.1)
thor (1.0.1)
thread_safe (0.3.6)
@ -406,6 +407,7 @@ DEPENDENCIES
select2-rails
selenium-webdriver
sprockets
table_print (~> 1.5, >= 1.5.7)
tiny_tds (= 1.3.0)
truncate_html
turbolinks (~> 5)

View File

@ -12,6 +12,7 @@ class Admin::LineStocksController < ApplicationController
def index
@line_stocks = LineStock.all
ap @line_stocks
date_regex = /^(0[1-9]|[12][0-9]|3[01])[\/](0[1-9]|1[012])[\/](19|20)\d\d$/i
@ -121,14 +122,18 @@ class Admin::LineStocksController < ApplicationController
end
def stock_resume
@p_product_refs = PProductRef.order(:name).all
@p_product_refs = PProductRef.distinct.all
if params[:code].to_s != ""
@p_product_refs = @p_product_refs.where("p_product_refs.code LIKE ?","%#{params[:code]}%")
if params[:search][:p_product_cat_id].to_s != ""
if params[:search][:p_product_cat_id].to_s == "null"
@p_product_refs = @p_product_refs.joins(:p_product).where("p_product_cat_id = ?", nil)
else
@p_product_refs = @p_product_refs.joins(:p_product).where("p_product_cat_id = ?", params[:search][:p_product_cat_id])
end
end
if params[:name].to_s != ""
@p_product_refs = @p_product_refs.where("p_product_refs.name LIKE ?","%#{params[:name]}%")
if params[:p_product_ref_id].present?
@p_product_refs = PProductRef.where(id: params[:p_product_ref_id])
end
end

View File

@ -13,7 +13,7 @@ class Admin::PSpecValuesController < ApplicationController
def index
@p_spec_values = PSpecValue.all
@p_spec_values = sort_by_sorting(@p_spec_values, "value + 0 ASC")
@p_spec_values = sort_by_sorting(@p_spec_values, "value ASC")
respond_to do |format|
format.html{

View File

@ -0,0 +1,220 @@
# -*- encoding : utf-8 -*-
class Admin::SInventairesController < ApplicationController
layout "admin"
before_action :auth_admin, :except => :print
before_action :admin_space
def admin_space
@admin_space = "stocks"
end
def index
@s_inventaires = SInventaire.all
@s_inventaires = sort_by_sorting(@s_inventaires, "id DESC")
respond_to do |format|
format.html{
params[:search][:per_page] = params[:search][:per_page] || 100
per_page = params[:search][:per_page]
page = (params[:page] and params[:page] != "") ? params[:page] : 1
@s_inventaires = @s_inventaires.page(page).per(per_page)
}
end
end
def generate_stock
@s_inventaire = SInventaire.find(params[:id])
@s_inventaire.generate_stock
redirect_back :fallback_location => "/"
end
def show
@s_inventaire = SInventaire.find(params[:id])
@s_inventaire_lines =@s_inventaire.s_inventaire_lines
@s_inventaire_lines = sort_by_sorting(@s_inventaire_lines, "created_at DESC")
respond_to do |format|
format.html{
params[:search][:per_page] = params[:search][:per_page] || 100
per_page = params[:search][:per_page]
page = (params[:page] and params[:page] != "") ? params[:page] : 1
@s_inventaire_lines = @s_inventaire_lines.page(page).per(per_page)
}
format.csv {
@headers = []
@columns = []
SInventaireLine.qi_table_order.each do |key, value|
if value.instance_of? Hash
name = value[:name]
else
name = value
end
if name != "Actions"
@headers << name.to_s
@columns << key
end
end
xlsx_package = Axlsx::Package.new
wb = xlsx_package.workbook
wb.add_worksheet(name: "import") do |sheet|
sheet.add_row @headers
@s_inventaire_lines.each do |p_customer|
line = []
@columns.each do |column|
if (p_customer.respond_to?("csv_"+column.to_s))
line << p_customer.send("csv_"+column.to_s)
elsif (p_customer.respond_to?(column))
if p_customer.send(column.to_s).class.to_s == "BigDecimal"
line << p_customer.send(column.to_s) #.to_s.gsub('.', ',')
else
line << p_customer.send(column.to_s)
end
else
line << column.to_s
end
end
sheet.add_row line, types: line.map{|t| cell_type_from_value(t)}
end
end
@final_file = "#{Rails.root}/private_medias/export-inventaire-#{Time.now.to_s.to_slug}.xlsx"
xlsx_package.serialize(@final_file)
send_file @final_file
}
end
end
def print
@s_inventaire = SInventaire.find(params[:id])
params[:inline] = true
if !params[:html] # and !Rails.env.development?
doc_number = @s_inventaire.id
url = print_admin_s_inventaire_path(:id => @s_inventaire.id, :html => true)
Dir.mkdir("#{Rails.root}/pdf/s_inventaires") unless File.exists?("#{Rails.root}/pdf/s_inventaires")
@temp_file = "#{Rails.root}/pdf/s_inventaires/#{doc_number}_temp.pdf"
@final_file = "#{Rails.root}/pdf/s_inventaires/#{doc_number}_temp2.pdf"
@final_file2 = "#{Rails.root}/pdf/s_inventaires/#{doc_number}.pdf"
url = (Rails.env.development? ? "http://localhost:4000" : "http://shakal.olwen.xyz").to_s+url
puts url
stamp = "inventaire"
pdf = "pdf-inventaire"
node_file = @temp_file
puts "node #{pdf}.js #{Shellwords.escape(url)} #{Shellwords.escape(@temp_file)} 'Inventaire du #{@s_inventaire.date}'"
system("node #{pdf}.js #{Shellwords.escape(url)} #{Shellwords.escape(@temp_file)} 'Inventaire du #{@s_inventaire.date}'")
require 'posix/spawn'
::POSIX::Spawn::Child.new 'pdftk', @temp_file, 'stamp', "#{Rails.root}/pdf_stamp/#{stamp}.pdf", 'output', @final_file
@data_to_send = File.open(@final_file).read
send_data @data_to_send, :filename =>"#{doc_number}.pdf" , :type => 'application/pdf',:disposition => (params[:inline] ? 'inline' : "attachment")
#render :inline => "y"
else
render :layout => false
end
end
def new
@s_inventaire = SInventaire.new
end
def edit
@s_inventaire = SInventaire.find(params[:id])
end
def create
@s_inventaire = SInventaire.new(params.require(:s_inventaire).permit!)
if @s_inventaire.save
else
render action: "new"
end
end
def update
@s_inventaire = SInventaire.find(params[:id])
if @s_inventaire.update_attributes(params.require(:s_inventaire).permit!)
else
render action: "edit"
end
end
def destroy
@s_inventaire = SInventaire.find(params[:id])
@s_inventaire.destroy
end
end

View File

@ -102,7 +102,7 @@ class ApplicationController < ActionController::Base
end
if current_admin.has_permission?("boutique")
# set_sub_sub_menu :stocks, :p_preferences_products_menu, :p_product_colors, "Couleurs"
set_sub_sub_menu :products, :p_preferences_products_menu, :p_product_colors, "Couleurs"
#set_sub_sub_menu :stocks, :p_preferences_products_menu, :p_article_serial_nums, "Numeros série"
set_sub_sub_menu :products, :p_preferences_products_menu, :p_serial_num_types, "Types de Numero série"
set_sub_sub_menu :products, :p_preferences_products_menu, :p_product_ref_specs, "Specs"
@ -139,6 +139,10 @@ class ApplicationController < ActionController::Base
if current_admin.has_permission?("stocks")
set_sub_menu :achats, :line_stocks, "Lignes de stock", admin_line_stocks_path
set_sub_menu :achats, :stock_movements, "Mouvements de stock manuel", admin_stock_movements_path
set_sub_menu :achats, :line_stocks_resume, "Résumé des stocks", stock_resume_admin_line_stocks_path
set_sub_menu :achats, :s_inventaire, "Inventaires", admin_s_inventaires_path
end
# Stock

View File

@ -2,8 +2,10 @@
module DocumentLineHelper
def link_to_remove_fields(name, f)
f.hidden_field(:_destroy) + link_to(name, "#",:onclick => "if(confirm('Voulez-vous vraiment supprimer cette ligne ?')) {remove_fields(this);return false;}else{return false;}")
def link_to_remove_fields(name, f, options={})
f.hidden_field(:_destroy) + link_to(name, "#",
:onclick => "if(confirm('Voulez-vous vraiment supprimer cette ligne ?')) {remove_fields(this);return false;}else{return false;}",
:class => (options[:class]))
end
def link_to_add_fields(name, f, association, options={})
@ -50,7 +52,12 @@ module DocumentLineHelper
end
end
link_to name,"#", :onclick => "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\");return false;", :class => (options[:class]), tabindex: options[:tabindex], style: options[:style]
link_to name,"#",
:onclick => "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\");return false;",
:class => (options[:class]),
tabindex: options[:tabindex],
style: options[:style]#,
#data: options["data-qty_to_reach"]
end
end

View File

@ -0,0 +1,72 @@
require "awesome_print"
class SInventaire < ApplicationRecord
acts_as_sorting :fields => {
:date => {:name => "Date", :reorder => true},
:done => {:name => "Fait ?", :reorder => true, :as => :boolean},
:exhaustive => {:name => "Exhaustif ?", :reorder => true, :as => :boolean},
:ok => {:name => "Validé ?", :reorder => true, :as => :boolean},
:stock_ok => {:name => "Stock ok ?", :reorder => true, :as => :boolean},
:actions => {:name => "Actions"},
}
has_many :s_inventaire_lines
def generate_stock
self.s_inventaire_lines.each do |s_inventaire_line|
if s_inventaire_line.p_product_ref
line_stocks = LineStock.where(p_product_ref: s_inventaire_line.p_product_ref)
qte_difference = s_inventaire_line.qte - line_stocks.sum(:qte_available)
if line_stocks.present?
if qte_difference.positive? #make a credit
LineStock.create(:date => self.date, :p_product_ref => s_inventaire_line.p_product_ref, :description => "Entrée en stock par inventaire n°#{self.id}", :qte => qte_difference, :price_ht => s_inventaire_line.cc_pu_avg_ht * qte_difference, :s_inventaire => self, :s_inventaire_line => s_inventaire_line, :stockable => self)
elsif qte_difference.negative? #make a debit
decr_line_stock = LineStock.create(:date => self.date, :p_product_ref => s_inventaire_line.p_product_ref, :description => "Sortie de stock par inventaire n°#{self.id}", :qte => qte_difference, :price_ht => 0.0, :s_inventaire => self, :s_inventaire_line => s_inventaire_line, :stockable => self)
price = 0.0
line_stock_usages = []
qte_to_affect = qte_difference * -1
LineStock.where(:p_product_ref_id => s_inventaire_line.p_product_ref).where("date <= ?", self.date).where("qte_available > 0.0").each do |ls|
if qte_to_affect <= ls.qte_available
qte_here = qte_to_affect
else
qte_here = ls.qte_available
end
qte_to_affect = qte_to_affect - qte_here
lsu = LineStockUsage.create(:qte => qte_here, :line_stock => ls, :dest_line_stock_id => decr_line_stock.id)
line_stock_usages << lsu
price += lsu.price_ht
ls.save
break if qte_to_affect == 0.0
end
decr_line_stock.price_ht = price * -1
decr_line_stock.save
else #qte_difference == zero do nothing
end
else #make a credit
LineStock.create(:date => self.date, :p_product_ref => s_inventaire_line.p_product_ref, :description => "Entrée en stock par inventaire n°#{self.id}", :qte => qte_difference, :price_ht => s_inventaire_line.cc_pu_avg_ht * qte_difference, :s_inventaire => self, :s_inventaire_line => s_inventaire_line, :stockable => self)
end
end
end
if self.exhaustive
protected_refs = []
self.s_inventaire_lines.each do |il|
protected_refs << il.p_product_ref.id
end
line_stocks = LineStock.where.not(p_product_ref_id: protected_refs).where.not(qte_available: 0)
line_stocks.each do |ls|
decr_line_stock = LineStock.create(:date => self.date, :p_product_ref => ls.p_product_ref, :description => "Sortie de stock par inventaire n°#{self.id}", :qte => ls.qte_available * -1, :price_ht => 0.0, :s_inventaire => self, :stockable => self)
lsu = LineStockUsage.create(:qte => ls.qte_available , :line_stock => ls, :dest_line_stock_id => decr_line_stock.id)
decr_line_stock.price_ht = lsu.price_ht * -1
decr_line_stock.save
ls.save
end
end
self.stock_ok = true
self.save
end
end

View File

@ -16,14 +16,57 @@
%td
Produit :
%td
%input.form-control{:name => "p_product_ref", :class => "p_product_ref_autocomplete_input", :type => "text", :value => params[:p_product_ref]}
= hidden_field_tag "p_product_ref_id".to_sym, params[:p_product_ref_id], :class => "p_product_ref_id"
:javascript
qi_autocomplete('p_product_ref');
$( function() {
$('.p_product_ref_autocomplete_input').autocomplete({
source: function( request, response ) {
$.ajax( {
url: "/admin/p_product_refs/autocomplete.json",
dataType: "json",
data: {
search: request.term,
//enabled: true,
p_customer_id: $(".p_customer_id").val()
},
success: function(data){
arr = jQuery.map( data, function( item ) {
return {
label: item.member_label,
value: item.member_label,
id: item.id
}
});
response(arr)
}
} );
},
minLength: 2,
select: function( event, ui ) {
$(this).next(".p_product_ref_id").val(ui.item.id)
form = $(this).closest(".price_line_form")
//return false
}
});
} );
%td
Catégorie :
%td
=select_tag("search[p_product_cat_id]", options_for_select([["",""],["Aucune","null"]]+PProductCat.order(:name).all.map{|a| [a.name, a.id]}, params[:search][:p_product_cat_id]), {:class => 'form-control'})
=link_to ic(:search)+" Rechercher", "#", :class => "btn btn-default btn-qi-search", :onclick => "$(this).closest('form').submit();$(this).html('...');return false;"
@ -44,55 +87,24 @@
%thead.header
%tr
%th ID
%th Code
/ %th Code
%th Produit
%th Variante
%th Unités en stock
%th En Stock
%th Valorisation de stock
-if false
%th Unités sorties
%th Sorties (KG)
%th Sorties (€)
%tbody
-if params[:p_product_ref_id].present?
-PProductRef.where(p_product_id: params[:p_product_ref_id]).each do |p|
-@line_stocks = LineStock.where(p_product_ref_id: params[:p_product_ref_id])
%tr
%td=params[:p_product_ref_id]
%td=p.code
%td=p.name
%td=@line_stocks.sum(:qte_available)
%td=@line_stocks.sum(:cc_qte_kg_available).to_i
%td=number_to_currency @line_stocks.sum(:price_ht)
%td=@line_stocks.sum(:qte_used)
%td=@line_stocks.sum(:cc_qte_kg_used).to_i
%td=number_to_currency @line_stocks.sum(:cc_price_ht_used)
-else
-PProductRef.all.each do |p|
-@p_product_refs.each do |p|
-@line_stocks = LineStock.where(p_product_ref_id: p.id)
%tr
%td=p.p_product_id
%td=p.code
%td=p.id
%td=p.name
%td=p.ct_sub_name
%td=@line_stocks.sum(:qte_available)
%td=@line_stocks.sum(:cc_qte_kg_available).to_i
%td=number_to_currency @line_stocks.sum(:price_ht)
-if false
%td=@line_stocks.sum(:qte_used)
%td=@line_stocks.sum(:cc_qte_kg_used).to_i
%td=number_to_currency @line_stocks.sum(:cc_price_ht_used)

View File

@ -35,4 +35,5 @@
= form.semantic_fields_for :p_article_serial_nums do |form|
=render :partial => "admin/p_article_serial_nums/form", :locals => {:form => form}
%p= link_to_add_fields "Ajouter un numéro de série", form, :p_article_serial_nums, {:class => "btn btn-primary"}
%p.destroy{class: "btn btn-danger"}=link_to_remove_fields "Supprimer l'article", form
%p.destroy=link_to_remove_fields "Supprimer l'article", form, {:class => "btn btn-danger"}

View File

@ -29,11 +29,8 @@
-# =form.input :ct_sorecop, :label => "Sorecop personalisée :"
-# %td
-# =form.input :sorecop_comment, :label => "Commentaire de Sorecop :"
%td
=form.input :ct_deee, :label => "DEEE personalisée :"
-# %td
-# =form.input :ct_deee, :label => "DEEE personalisée :"
%tr
%td{:colspan => 4}

View File

@ -7,4 +7,8 @@
=render :partial => "admin/p_articles/form", :locals => {:form => form, @price_line => f.object}
%p= link_to_add_fields "Ajouter un article", f, :p_articles, {:class => "btn btn-primary"} if f.object.p_articles.count < f.object.qte
%p= link_to_add_fields "Ajouter un article", f, :p_articles, {:class => "btn btn-primary disabled"} if f.object.p_articles.count >= f.object.qte
=render :partial => "qi/actions", :locals => {:f => f}
-# .actions=f.submit "sauvegarder", :class => "btn btn-primary"

View File

@ -2,7 +2,7 @@
.content
= form.input :p_product_ref, label: "Produit :" if form.object.p_product_ref
= form.input :qte, label: "Quantité à satisfaire :"
= form.input :qte, label: "Quantité à satisfaire :", class: "small-input", as: :number
= form.input :ct_u_price_ht, :label => "Prix vente"
= form.input :comment, :label => "Commentaire", :input_html => {:style => "height:70px;"}

View File

@ -0,0 +1,18 @@
=semantic_form_for [:admin, @s_inventaire], :remote => true do |f|
.content
=f.inputs do
= f.input :date, :label => "Date :", :as => :date
= f.input :exhaustive, :label => "Exhaustif ?"
-if params[:action] == "edit"
= f.input :done, :label => "Fait ?"
= f.input :ok, :label => "Validé ?"
=# f.input :stock_ok, :label => "Stock ok ?"
.actions=f.submit "sauvegarder", :class => "btn btn-primary"

View File

@ -0,0 +1,18 @@
%tr#s_inventaire_row{:id => s_inventaire.id}
-tr = {}
-tr[:actions] = capture do
%td.actions
= link_to i(:"trash-o"), [:admin, s_inventaire], method: :delete, data: { confirm: 'Voulez-vous vraiment supprimer cet enregistrement ? ' } , :remote => true
= link_to i(:pencil), edit_admin_s_inventaire_path(s_inventaire), :remote => true
= link_to i(:eye), admin_s_inventaire_path(s_inventaire), :remote => false
=render :partial => "qi/qi_ordered_table_object", :locals => {:tr => tr, :object => s_inventaire}

View File

@ -0,0 +1,2 @@
$('#s_inventaires_rows').prepend("<%= escape_javascript(render(@s_inventaire))%>");
close_pane_hover();

View File

@ -0,0 +1 @@
$('#s_inventaire_row_<%= @s_inventaire.id %>').remove();

View File

@ -0,0 +1 @@
show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);

View File

@ -0,0 +1,15 @@
.qi_header
.right= link_to ic(:plus)+' Ajouter', new_admin_s_inventaire_path(), :class => "btn btn-primary btn-ap-add", :remote => true
%h1
Inventaires
.qi_search_row
=form_tag "", :method => "get", :onsubmit => "" do
=render :partial => "qi/qi_ordered_table_search_footer", :locals => {:collection_object => @s_inventaires}
=render :partial => "qi/qi_ordered_table", :locals => {:qi_ordered_table_collection => @s_inventaires}

View File

@ -0,0 +1 @@
show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);

View File

@ -0,0 +1,68 @@
-@price_documents = PriceDocument.where("date >= ? and date <= ?", @s_inventaire.date-2.year, @s_inventaire.date+1.day )
-@price_lines = PriceLine.where(:cc_block_type => "Facture achat",:price_line_block_id => PriceLineBlock.where(:price_lineable_type => "PriceDocument", :price_lineable_id =>@price_documents.ids )).group(:p_product_ref_id)
-@p_product_ref_ids = @price_lines.map{|pl| pl.p_product_ref_id}
-@p_product_ref_ids = @p_product_ref_ids.compact
=#debug @p_product_ref_ids.length
-PProductRef.where(:id => @p_product_ref_ids).joins(:p_product).group("p_products.p_product_cat_id").each do |ppc|
-if !ppc.p_product.p_product_cat or !ppc.p_product.p_product_cat.exclude_inventaire
%h3{:style =>"text-align:center;text-transform:uppercase;"}
=#ppc.p_product.p_product_cat_id
-if ppc.p_product.p_product_cat
=ppc.p_product.p_product_cat.name
-else
Non catégorisé
%table.table.table-striped
%thead
%tr
%th Réf.
%th Libellé
%th{:style => "width:40px;"} Qté const.
%tbody
-PProductRef.joins(:p_product).order(:cc_name).where(:p_products => {:exclude_inventaire => false,:p_product_cat_id => ppc.p_product.p_product_cat_id}, :id => @p_product_ref_ids).each do |p_product_ref|
%tr
%td{:style => "width:100px;"}=p_product_ref.ref
%td=p_product_ref.name
%td{:style => "width:40px;"}
%div{:style => "page-break-after: always;"}
:scss
*{
font-family:Lato;
}
table{
border-collapse:collapse;
width:100%;
font-size:12px;
tr{
page-break-inside: avoid;
}
th,td{
padding:5px 5px;
border:1px solid gray;
}
h3{
font-size:18px;
text-align:center;
}
tr:nth-child(odd){
th,td{
background:#f9f9fe;
}
}
}

View File

@ -0,0 +1,62 @@
.qi_header
.right
= link_to i(:pencil), edit_admin_s_inventaire_path(@s_inventaire), :remote => true
%h1
Inventaires
%span
="##{@s_inventaire.id}"
%span
=l @s_inventaire.date if @s_inventaire.date
.right{:style => "padding:20px;"}
=link_to ic(:print)+" Imprimer les feuilles d'inventaire", print_admin_s_inventaire_path(@s_inventaire), :class => "btn btn-primary"
=link_to ic(:"file-excel")+" Exporter les données saisies (XLS)", admin_s_inventaire_path(@s_inventaire, :format => :csv), :class => "btn btn-primary"
-if !@s_inventaire.stock_ok
%br
%br
- if @s_inventaire.done && @s_inventaire.ok
-if @s_inventaire.exhaustive
%button.btn.btn-primary{"type" => "button", "data-toggle" => "modal", "data-target" => "#alertModal"}
Générer les stocks
-else
=link_to "Générer les stocks", generate_stock_admin_s_inventaire_path(@s_inventaire), :class => "btn btn-primary"
=link_to ic(:check)+" Indiquer comme fait", admin_s_inventaire_path(:id => @s_inventaire.id, :s_inventaire => {:done => true}), :class => "btn btn-primary", :remote => true, :method => :put unless @s_inventaire.done
=link_to ic(:check)+ic(:check)+" Valider", admin_s_inventaire_path(:id => @s_inventaire.id, :s_inventaire => {:ok => true}), :class => "btn btn-primary", :remote => true, :method => :put if !@s_inventaire.ok && @s_inventaire.done
.clear
%br
.qi_tab_header
.right= link_to 'Ajouter un produit ', new_admin_s_inventaire_line_path(:s_inventaire_id => @s_inventaire.id), :class => "btn btn-primary bgbd-ventes", :remote => true
%br
%br
=render :partial => "qi/qi_ordered_table", :locals => {:qi_ordered_table_collection => @s_inventaire_lines}
#alertModal.modal.fade{ "tabindex" =>"-1", "aria-labelledby" => "exampleModalLabel", "aria-hidden" => "true"}
.modal-dialog
.modal-content{"role" => "document"}
.modal-header
%h3.modal-title#exampleModalLabel
Attention, inventaire EXAUSTIF !
%button.close{"type" => "button", "data-dismiss" => "modal", "aria-label" => "Close"}
%span{"aria-hidden" => "true"}
&times;
.modal-body
Il s'agit d'un inventaire exhaustif.
%br
Tous les produits absents de l'inventaire seront débités des stocks. Voulez-vous générer les stocks ?
.modal-footer
=link_to "Générer les stocks", generate_stock_admin_s_inventaire_path(@s_inventaire), :class => "btn btn-primary"
%button.btn.btn-secondary{ "type" => "button", "data-dismiss" => "modal" } Annuler

View File

@ -0,0 +1,2 @@
$('#s_inventaire_row_<%= @s_inventaire.id %>').replaceWith("<%= escape_javascript(render(@s_inventaire))%>");
close_pane_hover();

View File

@ -452,6 +452,17 @@ Rails.application.routes.draw do
end
end
namespace :admin do
resources :s_inventaires do
member do
end
collection do
end
end
end
namespace :admin do
resources :p_devises do
member do

View File

@ -0,0 +1,13 @@
class CreateSInventaires < ActiveRecord::Migration[6.0]
def change
create_table :s_inventaires do |t|
t.date :date
t.boolean :done, :default => false
t.boolean :exhaustive, :default => false
t.boolean :ok, :default => false
t.boolean :stock_ok, :default => false
t.timestamps
end
end
end