From 8f89898817df7309dfc0cf433a54895e1231d4a1 Mon Sep 17 00:00:00 2001 From: Philippe Date: Thu, 18 Nov 2021 17:47:00 +0100 Subject: [PATCH] adding stock resume --- .../(__TEMPLATE__)c | Bin 5965 -> 1374 bytes Gemfile | 4 +- Gemfile.lock | 2 + .../admin/line_stocks_controller.rb | 15 +- .../admin/p_spec_values_controller.rb | 2 +- .../admin/s_inventaires_controller.rb | 220 ++++++++++++++++++ app/controllers/application_controller.rb | 6 +- app/helpers/document_line_helper.rb | 13 +- app/models/s_inventaire.rb | 72 ++++++ .../admin/line_stocks/stock_resume.html.haml | 110 +++++---- app/views/admin/p_articles/_form.html.haml | 3 +- .../admin/p_product_refs/_form.html.haml | 7 +- .../price_lines/_add_p_article_form.html.haml | 4 + .../_reponse_pane_hover_form.html.haml | 2 +- app/views/admin/s_inventaires/_form.html.haml | 18 ++ .../s_inventaires/_s_inventaire.html.haml | 18 ++ app/views/admin/s_inventaires/create.js.erb | 2 + app/views/admin/s_inventaires/destroy.js.erb | 1 + app/views/admin/s_inventaires/edit.js.erb | 1 + app/views/admin/s_inventaires/index.html.haml | 15 ++ app/views/admin/s_inventaires/new.js.erb | 1 + app/views/admin/s_inventaires/print.html.haml | 68 ++++++ app/views/admin/s_inventaires/show.html.haml | 62 +++++ app/views/admin/s_inventaires/update.js.erb | 2 + config/routes.rb | 11 + .../20211118154549_create_s_inventaires.rb | 13 ++ 26 files changed, 604 insertions(+), 68 deletions(-) create mode 100644 app/controllers/admin/s_inventaires_controller.rb create mode 100644 app/models/s_inventaire.rb create mode 100644 app/views/admin/s_inventaires/_form.html.haml create mode 100644 app/views/admin/s_inventaires/_s_inventaire.html.haml create mode 100644 app/views/admin/s_inventaires/create.js.erb create mode 100644 app/views/admin/s_inventaires/destroy.js.erb create mode 100644 app/views/admin/s_inventaires/edit.js.erb create mode 100644 app/views/admin/s_inventaires/index.html.haml create mode 100644 app/views/admin/s_inventaires/new.js.erb create mode 100644 app/views/admin/s_inventaires/print.html.haml create mode 100644 app/views/admin/s_inventaires/show.html.haml create mode 100644 app/views/admin/s_inventaires/update.js.erb create mode 100644 db/migrate/20211118154549_create_s_inventaires.rb diff --git a/.sass-cache/f6b9a0b1905a68d5dbb2139e95d49cba92f6fa93/(__TEMPLATE__)c b/.sass-cache/f6b9a0b1905a68d5dbb2139e95d49cba92f6fa93/(__TEMPLATE__)c index f14f6942a4eff9a4b9af0c9026e5b8e2e708b671..e1c3ae14c64ffb6b86d264611307231a215c18c3 100644 GIT binary patch delta 389 zcmX@BcaKZYSkGL~gv-Ft$jCf3HQB=4I4#v6HPtxPBq=#1&D_W+H6It+*WW5_3~Mm3W{MlU*3sGxAOT!WauA zgP5*QUc@3R#*>m+T#%Dk$!5(NV#V!HmY7qT8qGFYo>zSGdlp?8&b<7*RInVcLw-R? zW`16AH3QJ(lFEYA$(F48%IwzS`PLGg){^!FD8Pv&LQl7O1)pl>bfAZ0D*AZ;yVV6Ew(F}aIP8t9#DHaRm5D?W#k v)Lfu%N`SsrfrUpkmx2P+lU5+#SaWgJa&d8iJOy+U+vJbjiacy^Qw>7^kL+bZ literal 5965 zcmbVQUvt~W5f?Qbii9jtbo9@ZEVHzu*orOEk{sE0Gwmg=JYgnrG#1krJz$RHi9!S7 zPym#pdi>UWh4f?eOSNC2eQb9Re~w2&ij*hfh}*s2?(P0|7yG-1y9d_c!NDQ#?RC4a z&iLMo?w)8J?Dt;r=l$Nx7hJsT9f~iyqPyR+epiy@-U$ywLOOvEguIh7dMo?l4q0Tq zbI0um!aFTbZW_4)H&uwm0(d?xwi{~?yRv_2hY^pQFmnDn5@C@Pk2>To^LY@8zKuIW zNgDBSC&CrINCt$wmct=G5g_69M2Rf0p%`{W5S|t#xj(r%-8VNw?l5_F z7K#WS7ntz+N`%(bOS<8#!_f$_1yI3y8AKvzp&-2*|HO}EgN2FDZ37=&FVlNc>nqaD zvDG@g-)?;J*tR=I-yMJZW#`DYpA^ACbW4(YjJlm13PJP+aDwKJ%Sg~6E^pK)C+zI1b6Mr)MRR}EnL|f^(xS`RQFKjS@6{!GzeTt3dXzB!B##da$vL>+Qg$D>x=Zh~8r@|8sY@TY!Y6Q!}IKdyCapKFPl4E-urP7$dT74kGjsl?nze$M#k2E9|sWk zB3j>Rs`~)1UHXE|hnNKs_-+Qwg+P=(Mrin929TE~3@!msD}#+IlER*#lH)-7NF_^j z2`^(sV|=FIsVmvWR8NBKq!&1Tl+x9=4g@=QOLTi`!=KS|LQbLpqM%H-k)pnM{o<>` zug0uY>YuPz^fOX%`e2`P=7@kaSYP;o=OhIEWMQ_gNoolT>(b;xX;eu+AHx{ie#?w+ zWEqcV!HqBccAROo$Z#HqV$_%OWSOY|1CRA=m9=q*Z9XNlh7>GW0KecT)8ePxB^Lo#7dHWdWS-qw;QL;9hLYup(v|9#%VEMkot6z zr&LBiqmRw3TTBBqNrOeers=i(Oq=( z(!`ldaLQulS6pqSXDW(s(v}H2Pk{z)DtI1O6IS@Ual%4&!k$rX5-hCnbGkvBUG2)C zFM?-*GdPb_9w03n)~_D;Kh;C&I{ow()IPyK z^M5f;Sk6u`%}=nf!auSN84WI^xLKI#GDCTs%WAo7rM&U0{l#@WwS1E-)wzabyOCw7 z60SPS5QOT{%+h7pt0i#-l2>Kv{w=aJX(XnzZzXkUl6@<1roKsB?WYKI7*1p#d6aPW zL|YI>No#Ll=OhJ6`QE2sXD6@-dY9!EN7vJt9z-p=v`Jzflk<)0DU{c5zC_6XQkHe3#{~H zg?XbPG*d8>*(1*ZZ_Plb0X>m~?%4Qukx3u{_|t7SP#gfhftbnzxM2X)#0CJt*FTEO z_dqHz|7^wX{2_8&Lf*ND=b&|heb5tN9|!Fwl&>N8;dh>ezRO`0gALH^ z5A1k(1(J$^w38A6pX>PYmMm7xYc z(Uk#Lx`9uJ(5ySUdV(`rg==TAv{%?jothMg4LG`%c^6ktvzy2bhCBs27)%9eFwAZh zj3czIX0wohVY3ekDTwKexTaOSkq0&>Jg^BiuV(OY^*B8|pAqsDXb+eQG7q%02XMz# z`H+BNv(GaR=!B@H$k}W~t22XVKb;k!7QiPXWOMi+H~VgO`di`$t6tY1YH(GrH=Fuv z!Og}65Yi&o3=E+Dqh)=xa=W;jOr!{~*}TOdV;FNivRLcnph4lp@eZA6!c8V33I^p{ zbbGWhhB~%Kj}?-qb!Y^hj14~5;2A3b3ez+fBA}aIRAO|3C};XZv#q3w%DzY>jDiia NrnY#MHog0u{{w}+6Mp~z diff --git a/Gemfile b/Gemfile index c9515d0..def2338 100644 --- a/Gemfile +++ b/Gemfile @@ -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' diff --git a/Gemfile.lock b/Gemfile.lock index d374180..488c30a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/app/controllers/admin/line_stocks_controller.rb b/app/controllers/admin/line_stocks_controller.rb index ea968b2..358e84a 100644 --- a/app/controllers/admin/line_stocks_controller.rb +++ b/app/controllers/admin/line_stocks_controller.rb @@ -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 diff --git a/app/controllers/admin/p_spec_values_controller.rb b/app/controllers/admin/p_spec_values_controller.rb index 4ddb464..659c344 100644 --- a/app/controllers/admin/p_spec_values_controller.rb +++ b/app/controllers/admin/p_spec_values_controller.rb @@ -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{ diff --git a/app/controllers/admin/s_inventaires_controller.rb b/app/controllers/admin/s_inventaires_controller.rb new file mode 100644 index 0000000..36d2a7d --- /dev/null +++ b/app/controllers/admin/s_inventaires_controller.rb @@ -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 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 032fe7b..bc5e837 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -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 diff --git a/app/helpers/document_line_helper.rb b/app/helpers/document_line_helper.rb index 88a9a6e..ae0b4c6 100644 --- a/app/helpers/document_line_helper.rb +++ b/app/helpers/document_line_helper.rb @@ -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 diff --git a/app/models/s_inventaire.rb b/app/models/s_inventaire.rb new file mode 100644 index 0000000..1695de9 --- /dev/null +++ b/app/models/s_inventaire.rb @@ -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 diff --git a/app/views/admin/line_stocks/stock_resume.html.haml b/app/views/admin/line_stocks/stock_resume.html.haml index 8c8838f..e0a3439 100644 --- a/app/views/admin/line_stocks/stock_resume.html.haml +++ b/app/views/admin/line_stocks/stock_resume.html.haml @@ -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 - %th Unités sorties - %th Sorties (KG) - %th Sorties (€) + -if false + %th Unités sorties + %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) + -@p_product_refs.each do |p| + -@line_stocks = LineStock.where(p_product_ref_id: p.id) + %tr + %td=p.id + %td=p.name + %td=p.ct_sub_name + %td=@line_stocks.sum(:qte_available) + -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) - -else - -PProductRef.all.each do |p| - -@line_stocks = LineStock.where(p_product_ref_id: p.id) - %tr - %td=p.p_product_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) - - - - - - - - - - - - - - diff --git a/app/views/admin/p_articles/_form.html.haml b/app/views/admin/p_articles/_form.html.haml index 7b42465..0931c59 100644 --- a/app/views/admin/p_articles/_form.html.haml +++ b/app/views/admin/p_articles/_form.html.haml @@ -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"} diff --git a/app/views/admin/p_product_refs/_form.html.haml b/app/views/admin/p_product_refs/_form.html.haml index a857132..6c5848c 100644 --- a/app/views/admin/p_product_refs/_form.html.haml +++ b/app/views/admin/p_product_refs/_form.html.haml @@ -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} diff --git a/app/views/admin/price_lines/_add_p_article_form.html.haml b/app/views/admin/price_lines/_add_p_article_form.html.haml index 33a2951..a8f2e10 100644 --- a/app/views/admin/price_lines/_add_p_article_form.html.haml +++ b/app/views/admin/price_lines/_add_p_article_form.html.haml @@ -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" diff --git a/app/views/admin/price_lines/_reponse_pane_hover_form.html.haml b/app/views/admin/price_lines/_reponse_pane_hover_form.html.haml index 22fce64..d431ed9 100644 --- a/app/views/admin/price_lines/_reponse_pane_hover_form.html.haml +++ b/app/views/admin/price_lines/_reponse_pane_hover_form.html.haml @@ -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;"} diff --git a/app/views/admin/s_inventaires/_form.html.haml b/app/views/admin/s_inventaires/_form.html.haml new file mode 100644 index 0000000..e0b19de --- /dev/null +++ b/app/views/admin/s_inventaires/_form.html.haml @@ -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" + \ No newline at end of file diff --git a/app/views/admin/s_inventaires/_s_inventaire.html.haml b/app/views/admin/s_inventaires/_s_inventaire.html.haml new file mode 100644 index 0000000..0a84aa2 --- /dev/null +++ b/app/views/admin/s_inventaires/_s_inventaire.html.haml @@ -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} + + + + \ No newline at end of file diff --git a/app/views/admin/s_inventaires/create.js.erb b/app/views/admin/s_inventaires/create.js.erb new file mode 100644 index 0000000..6c44946 --- /dev/null +++ b/app/views/admin/s_inventaires/create.js.erb @@ -0,0 +1,2 @@ +$('#s_inventaires_rows').prepend("<%= escape_javascript(render(@s_inventaire))%>"); +close_pane_hover(); \ No newline at end of file diff --git a/app/views/admin/s_inventaires/destroy.js.erb b/app/views/admin/s_inventaires/destroy.js.erb new file mode 100644 index 0000000..a6cf96a --- /dev/null +++ b/app/views/admin/s_inventaires/destroy.js.erb @@ -0,0 +1 @@ +$('#s_inventaire_row_<%= @s_inventaire.id %>').remove(); \ No newline at end of file diff --git a/app/views/admin/s_inventaires/edit.js.erb b/app/views/admin/s_inventaires/edit.js.erb new file mode 100644 index 0000000..6c8f015 --- /dev/null +++ b/app/views/admin/s_inventaires/edit.js.erb @@ -0,0 +1 @@ +show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900); \ No newline at end of file diff --git a/app/views/admin/s_inventaires/index.html.haml b/app/views/admin/s_inventaires/index.html.haml new file mode 100644 index 0000000..becc3de --- /dev/null +++ b/app/views/admin/s_inventaires/index.html.haml @@ -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} + + + diff --git a/app/views/admin/s_inventaires/new.js.erb b/app/views/admin/s_inventaires/new.js.erb new file mode 100644 index 0000000..6c8f015 --- /dev/null +++ b/app/views/admin/s_inventaires/new.js.erb @@ -0,0 +1 @@ +show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900); \ No newline at end of file diff --git a/app/views/admin/s_inventaires/print.html.haml b/app/views/admin/s_inventaires/print.html.haml new file mode 100644 index 0000000..ff3d182 --- /dev/null +++ b/app/views/admin/s_inventaires/print.html.haml @@ -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; + } + } + } + + \ No newline at end of file diff --git a/app/views/admin/s_inventaires/show.html.haml b/app/views/admin/s_inventaires/show.html.haml new file mode 100644 index 0000000..2ef6e2b --- /dev/null +++ b/app/views/admin/s_inventaires/show.html.haml @@ -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"} + × + .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 diff --git a/app/views/admin/s_inventaires/update.js.erb b/app/views/admin/s_inventaires/update.js.erb new file mode 100644 index 0000000..f730efc --- /dev/null +++ b/app/views/admin/s_inventaires/update.js.erb @@ -0,0 +1,2 @@ +$('#s_inventaire_row_<%= @s_inventaire.id %>').replaceWith("<%= escape_javascript(render(@s_inventaire))%>"); +close_pane_hover(); \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index effb589..f4992e4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 diff --git a/db/migrate/20211118154549_create_s_inventaires.rb b/db/migrate/20211118154549_create_s_inventaires.rb new file mode 100644 index 0000000..bd0250e --- /dev/null +++ b/db/migrate/20211118154549_create_s_inventaires.rb @@ -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