Add front validations for p_article form, add p_article to stock_movement, add AJAX on price_line update method

TODO:
- AJAX for add_p_article and add_stock_movement_p_article in stock_movement views
- Fix select p_article with in stock_movement partial view
- Fix query to display available p_article in stock_movement partial
This commit is contained in:
Philippe 2021-11-23 20:20:41 +01:00
parent e4c91dcf7a
commit b32ddd37f5
28 changed files with 404 additions and 160 deletions

View File

@ -230,6 +230,10 @@ class Admin::PriceDocumentsController < ApplicationController
def show def show
@price_document = PriceDocument.find(params[:id]) @price_document = PriceDocument.find(params[:id])
@facture_achat_childrens = PriceDocument.where(doc_ref_id: @price_document.id, price_document_type: PriceDocumentType.find_by_label("Facture achat")) @facture_achat_childrens = PriceDocument.where(doc_ref_id: @price_document.id, price_document_type: PriceDocumentType.find_by_label("Facture achat"))
@price_line_qty_ok = []
@price_document.price_line_block.price_lines.each { |price_line| @price_line_qty_ok << price_line.affected_qty_ok}
@qty_in_br = PriceDocument.where(facture_achat_id: @price_document.id, cc_label: "Bon de réception achat").joins(price_line_block: [{ price_lines: :p_articles }]).count
@qty_to_reach = @price_document.price_line_block.price_lines.sum(:qte)
end end
def new def new
@ -753,7 +757,7 @@ class Admin::PriceDocumentsController < ApplicationController
@past_price_document.price_line_block.br_ok = true @past_price_document.price_line_block.br_ok = true
@past_price_document.save @past_price_document.save
end end
if price_document.save if price_document.save
#price_document.reset_for_update #price_document.reset_for_update
#price_document.archive_now #price_document.archive_now

View File

@ -45,7 +45,8 @@ class Admin::PriceLinesController < ApplicationController
def update def update
@price_line = PriceLine.find(params[:id]) @price_line = PriceLine.find(params[:id])
@price_document = @price_line.price_line_block.price_lineable
if @price_line.update_attributes(params.require(:price_line).permit!) if @price_line.update_attributes(params.require(:price_line).permit!)
else else

View File

@ -73,4 +73,15 @@ class Admin::StockMovementLinesController < ApplicationController
@stock_movement_line.destroy @stock_movement_line.destroy
end end
def add_p_article
@stock_movement_line = StockMovementLine.find(params[:stock_movement_line_id])
end
def add_stock_movement_line_p_article
@stock_movement_line = StockMovementLine.find(params[:stock_movement_line_id])
end
end end

View File

@ -90,4 +90,15 @@ module ApplicationHelper
end end
end end
def id_color_array(price_line)
if price_line.p_articles.count == 0
return "background-color", "red"
elsif price_line.p_articles.count < price_line.qte
return "background-color", "orange"
else
return "background-color", "#70ff29"
end
end
end end

View File

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

View File

@ -6,15 +6,18 @@ class PArticle < ApplicationRecord
has_one :p_product_color, through: :p_product_ref has_one :p_product_color, through: :p_product_ref
has_one :s_brand, through: :p_product_ref has_one :s_brand, through: :p_product_ref
has_many :p_article_serial_nums, dependent: :destroy
# has_many :p_serial_num_values, through: :p_article_serial_nums # has_many :p_serial_num_values, through: :p_article_serial_nums
has_many :p_article_serial_nums, dependent: :destroy
accepts_nested_attributes_for :p_article_serial_nums
has_many :price_line_p_articles has_many :price_line_p_articles
has_many :price_lines, through: :price_line_p_articles has_many :price_lines, through: :price_line_p_articles
accepts_nested_attributes_for :p_article_serial_nums
has_many :line_stock_p_articles has_many :line_stock_p_articles
has_many :line_stocks, through: :line_stock_p_articles has_many :line_stocks, through: :line_stock_p_articles
has_many :stock_movement_line_p_articles
has_many :stock_movement_lines, through: :stock_movement_line_p_articles
validates_presence_of :p_product_ref validates_presence_of :p_product_ref

View File

@ -19,8 +19,8 @@ class PriceLine < ApplicationRecord
validates :p_product_ref_id, :presence => true, :if => :p_product_ref_needed? validates :p_product_ref_id, :presence => true, :if => :p_product_ref_needed?
validates :p_product_id, :presence => true, :if => :p_product_needed? validates :p_product_id, :presence => true, :if => :p_product_needed?
validates :qte, :presence => true validates :qte, presence: true#, numericality: { greater_than_or_equal_to: :affected_qty }
validate :qte_greater_than_or_equal_to_affected_qty
attr_accessor :forced_price attr_accessor :forced_price
@ -618,4 +618,18 @@ class PriceLine < ApplicationRecord
PFournisseurRef.create(p_fournisseur: self.p_fournisseur, p_product_ref: self.p_product_ref, ref: self.ct_ref, label: self.ct_title) PFournisseurRef.create(p_fournisseur: self.p_fournisseur, p_product_ref: self.p_product_ref, ref: self.ct_ref, label: self.ct_title)
end end
def affected_qty_ok
return self.p_articles.count >= self.qte
end
def affected_qty
return self.p_articles.count
end
def qte_greater_than_or_equal_to_affected_qty
if self.affected_qty > self.qte
errors.add(:qte, "doit être supérieur ou égale à la quantité affectée")
end
end
end end

View File

@ -134,46 +134,40 @@ class PriceLineBlock < ApplicationRecord
:price_line_block => self, :price_line_block => self,
:stockable => self.price_lineable) :stockable => self.price_lineable)
price = 0.0 price = 0.0
line_stock_usages = [] line_stock_usages = []
#qte_to_affect = qte #qte_to_affect = qte
lsu_p_art = LineStockUsage.where(p_article_id: p_article.id) lsu_p_art = LineStockUsage.where(p_article_id: p_article.id)
line_stocks_p_article = p_article.line_stocks.where("qte_available > ?", 0) #LineStock.joins(:p_articles).where("p_articles.id = ?", p_article.id)
# ls = LineStock.joins(:p_articles).joins(:line_stock_usages).where("p_articles.id = ?", p_article.id).where.not("line_stock_usages.p_article").order(:date).last ls = nil
# ls = LineStock.joins(:p_articles).joins(:line_stock_usages).where("p_articles.id = ?", 69).where.not("line_stock_usages.p_article_id = ?", 69).order(:date).last line_stocks_p_article.each do |p_article_line_stock|
# used_line_stock_p_article = line_stocks_p_article.joins(:line_stock_usages).where("line_stock_usages.p_article_id = ?", p_article.id).order(date: :desc).last if p_article_line_stock.line_stock_usages.where(p_article_id: p_article).empty?
# line_stocks_p_article = LineStock.joins(:p_articles).where("p_articles.id = ?", p_article.id) ls = p_article_line_stock
line_stocks_p_article = p_article.line_stocks.where("qte_available > ?", 0) #LineStock.joins(:p_articles).where("p_articles.id = ?", p_article.id)
ls = nil
line_stocks_p_article.each do |p_article_line_stock|
if p_article_line_stock.line_stock_usages.where(p_article_id: p_article).empty?
ls = p_article_line_stock
end
end end
#ls = LineStock.joins(:p_articles).where("p_articles.id = ?", p_article.id).joins(:line_stock_usages)
#ls.qte_available = ls.qte_available - 1
#qte_to_affect = qte_to_affect - qte_here
lsu = LineStockUsage.create(:qte => 1, :line_stock => ls, :dest_line_stock_id => decr_line_stock.id, p_article_id: p_article.id)
#line_stock_usages << lsu
price += lsu.price_ht
ls.save
decr_line_stock.price_ht = price * -1
decr_line_stock.save
ls_p_art = LineStockPArticle.new(
p_article: p_article,
line_stock: decr_line_stock
)
ls_p_art.save
#p_article.line_stocks << decr_line_stock fonctionne aussi selon la doc : https://guides.rubyonrails.org/association_basics.html#:~:text=The%20collection%20of%20join%20models%20can%20be%20managed
end end
#ls = LineStock.joins(:p_articles).where("p_articles.id = ?", p_article.id).joins(:line_stock_usages)
#ls.qte_available = ls.qte_available - 1
#qte_to_affect = qte_to_affect - qte_here
lsu = LineStockUsage.create(:qte => 1, :line_stock => ls, :dest_line_stock_id => decr_line_stock.id, p_article_id: p_article.id)
#line_stock_usages << lsu
price += lsu.price_ht
ls.save
decr_line_stock.price_ht = price * -1
decr_line_stock.save
ls_p_art = LineStockPArticle.new(
p_article: p_article,
line_stock: decr_line_stock
)
ls_p_art.save
#p_article.line_stocks << decr_line_stock fonctionne aussi selon la doc : https://guides.rubyonrails.org/association_basics.html#:~:text=The%20collection%20of%20join%20models%20can%20be%20managed
end
else else
#=================================================================================================================== #===================================================================================================================

View File

@ -10,8 +10,6 @@ class StockMovement < ApplicationRecord
:movement_type => {:name => "Type de mouvement"}, :movement_type => {:name => "Type de mouvement"},
:stock_done => {:name => "Stock ok ?", :as => :boolean}, :stock_done => {:name => "Stock ok ?", :as => :boolean},
:actions => {:name => "Actions", :reorder => false} :actions => {:name => "Actions", :reorder => false}
} }
has_many :stock_movement_lines, :dependent => :destroy has_many :stock_movement_lines, :dependent => :destroy
@ -26,65 +24,105 @@ class StockMovement < ApplicationRecord
def generate_stock def generate_stock
if self.movement_type == "cred" if self.movement_type == "cred"
self.stock_movement_lines.each do |pl| self.stock_movement_lines.each do |stock_movement_line|
if pl.p_product_ref if stock_movement_line.p_product_ref
LineStock.create(:dluo => pl.dluo, :date => self.date, :p_product_ref => pl.p_product_ref, :description => "Entrée en stock par mouvement de stock manuel", :qte => pl.qte, :price_ht => pl.tot_amount_ht, :stock_movement_line => pl, :stockable => self) cred_line_stock = LineStock.new(:dluo => stock_movement_line.dluo,
:date => self.date,
end :p_product_ref => stock_movement_line.p_product_ref,
:description => "Entrée en stock par mouvement de stock manuel",
:qte => stock_movement_line.qte,
:price_ht => stock_movement_line.tot_amount_ht,
:stock_movement_line => stock_movement_line,
:stockable => self)
cred_line_stock.p_articles = stock_movement_line.p_articles
cred_line_stock.save
end
end end
self.stock_done = true self.stock_done = true
self.save self.save
return true return true
else else #self.movement_type == "deb"
if self.test_if_stock_ok? if self.test_if_stock_ok?
self.stock_movement_lines.each do |pl| self.stock_movement_lines.each do |sml|
if pl.p_product_ref if !sml.p_articles.empty?
decr_line_stock = LineStock.create(:date => self.date, :p_product_ref => pl.p_product_ref, :qte => pl.qte*-1, :description => "Attribution à une sortie de stock manuelle", :price_ht => 0.0, :stock_movement_line => pl, :stockable => self) sml.p_articles.each do |p_article|
puts "a" decr_line_stock = LineStock.create(:date => self.date,
puts decr_line_stock.id :p_product_ref => sml.p_product_ref,
puts "b" :qte => sml.qte*-1,
:description => "Attribution à une sortie de stock manuelle",
:price_ht => 0.0,
price = 0.0 :stock_movement_line => sml,
line_stock_usages = [] :stockable => self)
qte_to_affect = pl.qte price = 0.0
line_stock_usages = []
LineStock.where(:p_product_ref_id => pl.p_product_ref_id).where("date <= ?", self.date).where("qte_available > 0.0").each do |ls| #qte_to_affect = sml.qte
if qte_to_affect <= ls.qte_available
qte_here = qte_to_affect lsu_p_art = LineStockUsage.where(p_article_id: p_article.id)
else
qte_here = ls.qte_available line_stocks_p_article = p_article.line_stocks.where("qte_available > ?", 0)
ls = nil
line_stocks_p_article.each do |p_article_line_stock|
if p_article_line_stock.line_stock_usages.where(p_article_id: p_article).empty?
ls = p_article_line_stock
end
end end
qte_to_affect = qte_to_affect - qte_here lsu = LineStockUsage.create(:qte => 1, :line_stock => ls, :dest_line_stock_id => decr_line_stock.id, p_article_id: p_article.id)
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 price += lsu.price_ht
ls.save ls.save
decr_line_stock.price_ht = price * -1
break if qte_to_affect == 0.0 decr_line_stock.save
p_article.line_stocks << decr_line_stock
#price_u_ht decr_line_stock.price_ht = price * -1
decr_line_stock.save
end end
decr_line_stock.price_ht = price * -1
decr_line_stock.save
else
#==============================================================================================================================================================================================
if sml.p_product_ref
decr_line_stock = LineStock.create(:date => self.date, :p_product_ref => sml.p_product_ref, :qte => sml.qte*-1, :description => "Attribution à une sortie de stock manuelle", :price_ht => 0.0, :stock_movement_line => sml, :stockable => self)
puts "a"
puts decr_line_stock.id
puts "b"
price = 0.0
line_stock_usages = []
qte_to_affect = sml.qte
LineStock.where(:p_product_ref_id => sml.p_product_ref_id).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
#price_u_ht
end
decr_line_stock.price_ht = price * -1
decr_line_stock.save
end
#==============================================================================================================================================================================================
end end
end end
self.stock_done = true self.stock_done = true
self.save self.save

View File

@ -2,7 +2,17 @@ class StockMovementLine < ApplicationRecord
belongs_to :stock_movement belongs_to :stock_movement
belongs_to :p_product_ref belongs_to :p_product_ref
has_many :stock_movement_line_p_articles
has_many :p_articles, through: :stock_movement_line_p_articles
accepts_nested_attributes_for :stock_movement_line_p_articles
accepts_nested_attributes_for :p_articles, allow_destroy: true
acts_as_caching :fields => [:tot_amount_ht, :price_u_ht] acts_as_caching :fields => [:tot_amount_ht, :price_u_ht]
acts_as_sorting :fields => {
:qte => {:name => "Qté", :reorder => true},
:actions => {:name => "Actions"}
}
def ca_tot_amount_ht def ca_tot_amount_ht
if self.ct_tot_amount_ht if self.ct_tot_amount_ht

View File

@ -0,0 +1,4 @@
class StockMovementLinePArticle < ApplicationRecord
belongs_to :stock_movement_line
belongs_to :p_article
end

View File

@ -18,8 +18,6 @@
- elsif params[:controller] == "admin/price_lines" - elsif params[:controller] == "admin/price_lines"
.field .field
= form.inputs do = form.inputs do
=@price_line.price_line_block.price_lineable.tva_type_id
-if params[:p_product_ref_id] -if params[:p_product_ref_id]
= form.input :p_product_ref_id, as: :select, collection: PProductRef.all.distinct.pluck(:cc_name, :id), :label => form.object.label_for(:p_product_ref), input_html: {disabled: true} = form.input :p_product_ref_id, as: :select, collection: PProductRef.all.distinct.pluck(:cc_name, :id), :label => form.object.label_for(:p_product_ref), input_html: {disabled: true}
= form.hidden_field :p_product_ref_id, value: form.object.p_product_ref_id = form.hidden_field :p_product_ref_id, value: form.object.p_product_ref_id
@ -36,4 +34,24 @@
=render :partial => "admin/p_article_serial_nums/form", :locals => {:form => 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= link_to_add_fields "Ajouter un numéro de série", form, :p_article_serial_nums, {:class => "btn btn-primary"}
%p.destroy=link_to_remove_fields "Supprimer l'article", form, {:class => "btn btn-danger"} %p.destroy=link_to_remove_fields "Supprimer l'article", form, {:class => "btn btn-danger", js: "remove_disabledClass();"}
- elsif params[:controller] == "admin/stock_movement_lines"
.field
= form.inputs do
-if params[:p_product_ref_id]
= form.input :p_product_ref_id, as: :select, collection: PProductRef.all.distinct.pluck(:cc_name, :id), :label => form.object.label_for(:p_product_ref), input_html: {disabled: true}
= form.hidden_field :p_product_ref_id, value: form.object.p_product_ref_id
= form.input :tva_type_id, as: :select, collection: TvaType.pluck(:name, :id), :label => "Type de TVA"
-else
= form.input :p_product_ref_id, as: :select, collection: PProductRef.all.distinct.pluck(:cc_name, :id), :label => form.object.label_for(:p_product_ref)
-if PGrade::ACTIVATED
= form.input :p_grade, as: :select, collection: PGrade.pluck(:grade, :id), :label => "Grade"
%h4 Numero de série :
.p_article_serial_nums_form
= 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=link_to_remove_fields "Supprimer l'article", form, {:class => "btn btn-danger", js: "remove_disabledClass();"}

View File

@ -31,24 +31,29 @@
=render price_line_block =render price_line_block
%hr %hr
-# status : Brouillon Validée En Préparation En livraison Réceptionné Payée
-@bon_de_commande = @p_customer_sheet.price_documents.where(:cc_label => "Bon de commande client").first -@bon_de_commande = @p_customer_sheet.price_documents.where(:cc_label => "Bon de commande client").first
%p=link_to "Marquer l'offre comme refusée", reject_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn", style: "background:rgb(110,45,116); color: white;" -state = @p_customer_sheet.state
%p=link_to "Générer le bon de commande et marquer la commande comme Validée", generate_bc_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-success btn-ap-add disabled" if !@p_customer_sheet.stock_generable -if !state = "Refusée" and !state = "Validée" and !state = "En Préparation" and !state = "En Livraison" and !state = "Payée"
%p=link_to "Générer le bon de commande et marquer la commande comme Validée", generate_bc_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-success btn-ap-add" if @p_customer_sheet.stock_generable %p=link_to "Marquer l'offre comme refusée", reject_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn", style: "background:rgb(110,45,116); color: white;"
-if !state = "Refusée" and state = "Brouillon" and !state = "Validée" and !state = "En Préparation" and !state = "En Livraison" and !state = "Payée"
%p=link_to "Générer le bon de commande et marquer la commande comme Validée", generate_bc_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-success btn-ap-add disabled" if !@p_customer_sheet.stock_generable
%p=link_to "Générer le bon de commande et marquer la commande comme Validée", generate_bc_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-success btn-ap-add" if @p_customer_sheet.stock_generable
- if @bon_de_commande - if @bon_de_commande
-# %p=link_to "Générer le devis", generate_d_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-primary" -# %p=link_to "Générer le devis", generate_d_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-primary"
%p=link_to "Passer la commande en Préparation", admin_p_customer_sheet_path(:id => @p_customer_sheet.id, :p_customer_sheet => {:state => "Préparation"}), :method => :put, :class => "btn", style: "background:rgb(233,122,28); color: white" if !@bon_de_commande.stock_ok and @bon_de_commande.stock_generable -if !state = "Refusée" and state = "Validée" and !state = "En Livraison" and !state = "Payée"
%p=link_to "Générer le bon de livraison et marquer la commande comme Livraison", bl_admin_price_document_path(@bon_de_commande), :class => "btn btn-primary btn-ap-add" %p=link_to "Passer la commande en Préparation", admin_p_customer_sheet_path(:id => @p_customer_sheet.id, :p_customer_sheet => {:state => "Préparation"}), :method => :put, :class => "btn", style: "background:rgb(233,122,28); color: white" if !@bon_de_commande.stock_ok and @bon_de_commande.stock_generable
%p=link_to "Passer la commande en Livraison", admin_p_customer_sheet_path(:id => @p_customer_sheet.id, :p_customer_sheet => {:state => "Livraison"}), :method => :put, :class => "btn", style: "background:rgb(66,122,255); color: white" if !@bon_de_commande.stock_ok and @bon_de_commande.stock_generable -if !state = "Refusée" and !state = "Validée" and state = "En Préparation" and !state = "En Livraison" and !state = "Payée"
%p=link_to "Générer la facture", generate_f_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-primary" %p=link_to "Générer le bon de livraison et marquer la commande comme Livraison", bl_admin_price_document_path(@bon_de_commande), :class => "btn btn-primary btn-ap-add"
%p=link_to "Passer la commande en Livraison", admin_p_customer_sheet_path(:id => @p_customer_sheet.id, :p_customer_sheet => {:state => "Livraison"}), :method => :put, :class => "btn", style: "background:rgb(66,122,255); color: white" if !@bon_de_commande.stock_ok and @bon_de_commande.stock_generable
-if !state = "Refusée" and !state = "Validée" and !state = "En Préparation" and state = "En Livraison" and !state = "Payée"
%p=link_to "Générer la facture", generate_f_admin_p_customer_sheet_path(@p_customer_sheet), :class => "btn btn-primary"
%p=link_to "Mettre à jour les stocks", update_stocks_admin_price_document_path(@bon_de_commande), :class => "btn btn-primary" if !@bon_de_commande.stock_ok and @bon_de_commande.stock_generable %p=link_to "Mettre à jour les stocks", update_stocks_admin_price_document_path(@bon_de_commande), :class => "btn btn-primary" if !@bon_de_commande.stock_ok and @bon_de_commande.stock_generable
-if false -if false
-if @p_customer_sheet.demande_type? -if @p_customer_sheet.demande_type?
%p %p

View File

@ -209,20 +209,20 @@
-price_line_block.price_lines.each do |price_line| -price_line_block.price_lines.each do |price_line|
%tbody %tbody
%tr %tr{id: "price_line_row_#{price_line.id}"}
%td{style: id_color(price_line), id: "price_line_#{price_line.id}", onclick: "$('.p_articles_#{price_line.id}').toggle('800','swing');"} %td{style: id_color(price_line), id: "price_line_#{price_line.id}_id", onclick: "$('.p_articles_#{price_line.id}').toggle('800','swing');"}
="##{price_line.id}" ="##{price_line.id}"
%td %td
=price_line.ref =price_line.ref
%td %td
=price_line.p_product_ref.p_product.s_brand.name =price_line.p_product_ref.p_product.s_brand.name
%td{class: "p_product_ref_cc_name_#{@price_document.id}"} %td{id: "price_line_#{price_line.id}_p_product_ref_cc_name"}
=link_to price_line.p_product_ref.cc_name, edit_admin_p_product_path(price_line.p_product_ref.p_product) if price_line.p_product_ref and price_line.p_product_ref.p_product =link_to price_line.p_product_ref.cc_name, edit_admin_p_product_path(price_line.p_product_ref.p_product) if price_line.p_product_ref and price_line.p_product_ref.p_product
%td.numeraire{class: "price_line_qte_#{@price_document.id}"} %td.numeraire{id: "price_line_#{price_line.id}_qte"}
=price_line.qte =price_line.qte
%td.numeraire{class: "price_line_qte_#{@price_document.id}"} %td.numeraire{id: "price_line_#{price_line.id}_affected_qty"}
=price_line.p_articles.count =price_line.affected_qty
%td.numeraire{class: "price_line_price_u_ht_#{@price_document.id}"} %td.numeraire{id: "price_line_#{price_line.id}_price_u_ht"}
=number_to_currency price_line.price_u_ht =number_to_currency price_line.price_u_ht
%td.numeraire %td.numeraire
=price_line.tva_account_value.to_s+"%" =price_line.tva_account_value.to_s+"%"
@ -245,10 +245,12 @@
.qi_row .qi_row
-if current_admin.has_permission?("show-costs") -if current_admin.has_permission?("show-costs")
%p %p
-if @price_document.price_document_type_id == 6 -if @price_document.price_document_type_id == 6 #"Facture achat"
-# =link_to "Générer les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary" if !@price_document.stock_ok and @price_document.stock_generable -# =link_to "Générer les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary" if !@price_document.stock_ok and @price_document.stock_generable
-# =link_to "Générer les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary disabled" if !@price_document.stock_ok and !@price_document.stock_generable -# =link_to "Générer les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary disabled" if !@price_document.stock_ok and !@price_document.stock_generable
=link_to "Générer un bon de réception", bon_de_reception_admin_price_document_path(@price_document), :class => "btn btn-primary" if !@price_document.stock_ok
=link_to "Générer un bon de réception", bon_de_reception_admin_price_document_path(@price_document), :class => "btn btn-primary disabled" if !@price_document.stock_ok if @qty_in_br >= @qty_to_reach
=link_to "Générer un bon de réception", bon_de_reception_admin_price_document_path(@price_document), :class => "btn btn-primary" if !@price_document.stock_ok if @qty_in_br < @qty_to_reach
-elsif @price_document.price_document_type_id == 4 or @price_document.price_document_type_id == 5 -elsif @price_document.price_document_type_id == 4 or @price_document.price_document_type_id == 5
-# %p -# %p
@ -259,8 +261,8 @@
-# =number_to_currency @price_document.marge_ht -# =number_to_currency @price_document.marge_ht
-if !@price_document.cost_ok -if !@price_document.cost_ok
=link_to "Mettre à jour les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary" if !@price_document.stock_ok and @price_document.stock_generable =link_to "Mettre à jour les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary", id: "generate_stock_button_price_document_#{@price_document.id}" if !@price_document.stock_ok and @price_document.stock_generable
=link_to "Mettre à jour les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary disabled" if !@price_document.stock_ok and !@price_document.stock_generable =link_to "Mettre à jour les stocks", generate_stocks_admin_price_document_path(@price_document), :class => "btn btn-primary disabled", id: "generate_stock_button_price_document_#{@price_document.id}" if !@price_document.stock_ok and !@price_document.stock_generable
-if @price_document.d_number -if @price_document.d_number
-if @price_document.cc_label == "Commande achat" -if @price_document.cc_label == "Commande achat"

View File

@ -90,7 +90,7 @@
%td.numeraire %td.numeraire
=price_line.qte =price_line.qte
%td.numeraire %td.numeraire
= price_line.p_articles.count = price_line.affected_qty
= link_to i(:"mobile-alt"), add_price_line_p_article_admin_price_lines_path(p_product_ref_id: price_line.p_product_ref.id, price_line_id: price_line.id), :remote => true = link_to i(:"mobile-alt"), add_price_line_p_article_admin_price_lines_path(p_product_ref_id: price_line.p_product_ref.id, price_line_id: price_line.id), :remote => true
-if @price_document and @price_document.label != "Demande prix" and @price_document.label != "Réponse fournisseur" -if @price_document and @price_document.label != "Demande prix" and @price_document.label != "Réponse fournisseur"
%td.numeraire %td.numeraire

View File

@ -6,7 +6,7 @@
= f.semantic_fields_for :p_articles do |form| = f.semantic_fields_for :p_articles do |form|
=render :partial => "admin/p_articles/form", :locals => {:form => form, @price_line => f.object} =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", data: {qty_to_reach: @price_line.qte, qty: f.object.p_articles.count, btn_id: "add_p_article_id" }, js: "qty_check();"} if f.object.p_articles.count < f.object.qte %p= link_to_add_fields "Ajouter un article", f, :p_articles, {:class => "btn btn-primary", data: {qty_to_reach: @price_line.qte, qty: f.object.p_articles.count, btn_id: "add_p_article_id" }, js: "add_disabledClass();"} 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 %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
@ -14,24 +14,36 @@
-# .actions=f.submit "sauvegarder", :class => "btn btn-primary" -# .actions=f.submit "sauvegarder", :class => "btn btn-primary"
:javascript :javascript
var qty = parseInt($('[data-btn-id="add_p_article_id"]').data("qty")) var qty = parseInt($('[data-btn-id="add_p_article_id"]').data("qty"))
window.localStorage.setItem('qty', qty); window.localStorage.setItem('qty', qty);
console.log("ON PAGE LOAD " + window.localStorage.getItem('qty')) var qtyToReach = parseInt($('[data-btn-id="add_p_article_id"]').data("qty-to-reach"))
function add_disabledClass() {
function qty_check() {
//console.log($('[data-btn-id="add_p_article_id"]').length)
var qtyToReach = parseInt($('[data-btn-id="add_p_article_id"]').data("qty-to-reach"))
var qty = parseInt(window.localStorage.getItem('qty')) var qty = parseInt(window.localStorage.getItem('qty'))
console.log("qty " + qty)
qty += 1 qty += 1
console.log("qty " + qty)
window.localStorage.setItem('qty', qty); window.localStorage.setItem('qty', qty);
$('[data-btn-id="add_p_article_id"]').attr('data-qty', qty); $('[data-btn-id="add_p_article_id"]').attr('data-qty', qty);
if (qty >= qtyToReach) {
$('[data-btn-id="add_p_article_id"]').addClass('disabled')
} else {
$('[data-btn-id="add_p_article_id"]').removeClass('disabled')
}
}
function remove_disabledClass() {
var qty = parseInt(window.localStorage.getItem('qty'))
qty -= 1
window.localStorage.setItem('qty', qty);
$('[data-btn-id="add_p_article_id"]').attr('data-qty', qty);
if (qty >= qtyToReach) {
$('[data-btn-id="add_p_article_id"]').addClass('disabled')
} else {
$('[data-btn-id="add_p_article_id"]').removeClass('disabled')
}
} }

View File

@ -1,2 +1,12 @@
$('#price_line_row_<%= @price_line.id %>').replaceWith("<%= escape_javascript(render(@price_line))%>"); $('#price_line_<%= @price_line.id %>_qte').text(<%= @price_line.qte %>)
$('#price_line_<%= @price_line.id %>_affected_qty').text(<%= @price_line.affected_qty %>)
$('#price_line_<%= @price_line.id %>_id').css( "<%= id_color_array(@price_line)[0] %>", "<%= id_color_array(@price_line)[1] %>" )
<% if !@price_document.stock_ok and @price_document.stock_generable %>
$('#generate_stock_button_price_document_<%= @price_document.id %>').removeClass('disabled')
<% else %>
$('#generate_stock_button_price_document_<%= @price_document.id %>').addClass('disabled')
<% end %>
//$('#price_line_row_<%= @price_line.id %>').replaceWith("<%= escape_javascript(render(@price_line))%>");
close_pane_hover(); close_pane_hover();

View File

@ -0,0 +1,5 @@
= form.input :p_article_id,
as: :select,
collection: PArticle.available_articles.joins(:p_product_ref).where(p_product_ref: @stock_movement_line.p_product_ref).map{|p_article| [p_article.serialized_name, p_article.id]},
label: "Article(s) associé(s)",
input_html: {class:"p_article_select w-100"}

View File

@ -0,0 +1,49 @@
.mx-2.my-2
=semantic_form_for [:admin, @stock_movement_line], :remote => true do |f|
.content
=f.inputs do
.p_articles_form
= f.semantic_fields_for :p_articles do |form|
=render :partial => "admin/p_articles/form", :locals => {:form => form, @stock_movement_line => f.object}
%p= link_to_add_fields "Ajouter un article", f, :p_articles, {:class => "btn btn-primary", data: {qty_to_reach: @stock_movement_line.qte, qty: f.object.p_articles.count, btn_id: "add_p_article_id" }, js: "add_disabledClass();"}# 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"
:javascript
var qty = parseInt($('[data-btn-id="add_p_article_id"]').data("qty"))
window.localStorage.setItem('qty', qty);
var qtyToReach = parseInt($('[data-btn-id="add_p_article_id"]').data("qty-to-reach"))
function add_disabledClass() {
var qty = parseInt(window.localStorage.getItem('qty'))
qty += 1
window.localStorage.setItem('qty', qty);
$('[data-btn-id="add_p_article_id"]').attr('data-qty', qty);
if (qty >= qtyToReach) {
$('[data-btn-id="add_p_article_id"]').addClass('disabled')
} else {
$('[data-btn-id="add_p_article_id"]').removeClass('disabled')
}
}
function remove_disabledClass() {
var qty = parseInt(window.localStorage.getItem('qty'))
qty -= 1
window.localStorage.setItem('qty', qty);
$('[data-btn-id="add_p_article_id"]').attr('data-qty', qty);
if (qty >= qtyToReach) {
$('[data-btn-id="add_p_article_id"]').addClass('disabled')
} else {
$('[data-btn-id="add_p_article_id"]').removeClass('disabled')
}
}

View File

@ -0,0 +1,17 @@
.mx-2.my-2
=semantic_form_for [:admin, @stock_movement_line], :remote => true do |f|
.content
=f.inputs do
.stock_movement_line_p_articles_form
= f.semantic_fields_for :stock_movement_line_p_articles do |form|
= render "admin/stock_movement_line_p_articles/form", form: form, stock_movement_line: @stock_movement_line
%p= link_to_add_fields "Ajouter un article", f, :stock_movement_line_p_articles, {:class => "btn btn-primary add_stock_movement_line_p_article"} if @stock_movement_line.p_articles.count < @stock_movement_line.qte
=render :partial => "qi/actions", :locals => {:f => f}
:javascript
$('.p_article_select').select2();
$('.add_stock_movement_line_p_article').click(function() {
$('.p_article_select').last().select2();
});

View File

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

View File

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

View File

@ -20,51 +20,55 @@
%h3 Contenu %h3 Contenu
%table.table.table-hover.table-stripped %table.table.table-hover.table-stripped
%tr %tr
%th %th ID
Produit %th Produit
%th %th DLUO ??
DLUO
%th Qté %th Qté
%th Prix / conditionnement %th Prix / conditionnement
%th Valeur %th Valeur
-@stock_movement.stock_movement_lines.each do |sml| %th Actions
-@stock_movement.stock_movement_lines.each do |stock_movement_line|
%tr %tr
%td %td
=sml.p_product_ref.name if sml.p_product_ref =stock_movement_line.id
%td %td
=l sml.dluo if sml.dluo =stock_movement_line.p_product_ref.name if stock_movement_line.p_product_ref
%td %td
=sml.qte =l stock_movement_line.dluo if stock_movement_line.dluo
%td %td
=number_to_currency(sml.tot_amount_ht / sml.qte) if sml.tot_amount_ht =stock_movement_line.qte
%td %td
=number_to_currency sml.tot_amount_ht =number_to_currency(stock_movement_line.tot_amount_ht / stock_movement_line.qte) if stock_movement_line.tot_amount_ht
%td
=number_to_currency stock_movement_line.tot_amount_ht
%td.actions
= link_to i(:"trash-o"), admin_stock_movement_line_path(stock_movement_line), method: :delete, data: { confirm: 'Voulez-vous vraiment supprimer cet enregistrement ? ' } , :remote => true
= link_to i(:pencil), edit_admin_stock_movement_line_path(stock_movement_line), :remote => true
= link_to i(:eye), admin_stock_movement_line_path(stock_movement_line), :remote => true
-if @stock_movement.movement_type == "cred"
= link_to i(:"mobile-alt"), add_p_article_admin_stock_movement_lines_path(p_product_ref_id: stock_movement_line.p_product_ref.id, stock_movement_line_id: stock_movement_line.id), :remote => true
-else
= link_to i(:"mobile-alt"), add_stock_movement_line_p_article_admin_stock_movement_lines_path(p_product_ref_id: stock_movement_line.p_product_ref.id, stock_movement_line_id: stock_movement_line.id), :remote => true
%p.mt-5
%br
%br
%p
=link_to "Générer les stocks", generate_stocks_admin_stock_movement_path(@stock_movement), :class => "btn btn-primary" if !@stock_movement.stock_done =link_to "Générer les stocks", generate_stocks_admin_stock_movement_path(@stock_movement), :class => "btn btn-primary" if !@stock_movement.stock_done
%h3 Stocks générés -if @stock_movement.stock_done
#bills %h3 Stocks générés
-params[:search][:per_page] = params[:search][:per_page] || 5000 #bills
-per_page = params[:search][:per_page] -params[:search][:per_page] = params[:search][:per_page] || 5000
-page = (params[:page] and params[:page] != "") ? params[:page] : 1 -per_page = params[:search][:per_page]
-page = (params[:page] and params[:page] != "") ? params[:page] : 1
-@line_stocks = @stock_movement.line_stocks -@line_stocks = @stock_movement.line_stocks
-@line_stocks = sort_by_sorting(@line_stocks, "date DESC") -@line_stocks = sort_by_sorting(@line_stocks, "date DESC")
-@line_stocks = @line_stocks.page(page).per(per_page) -@line_stocks = @line_stocks.page(page).per(per_page)
%br %br
.clear .clear
=render :partial => "qi/qi_ordered_table", :locals => {:qi_ordered_table_collection => @line_stocks} =render :partial => "qi/qi_ordered_table", :locals => {:qi_ordered_table_collection => @line_stocks}

View File

@ -412,6 +412,8 @@ Rails.application.routes.draw do
end end
collection do collection do
get :add_p_article
get :add_stock_movement_line_p_article
end end
end end

View File

@ -0,0 +1,10 @@
class CreateStockMovementLinePArticles < ActiveRecord::Migration[6.0]
def change
create_table :stock_movement_line_p_articles do |t|
t.belongs_to :p_article
t.belongs_to :stock_movement_line
t.timestamps
end
end
end

View File

@ -0,0 +1,11 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value

View File

@ -0,0 +1,7 @@
require 'test_helper'
class StockMovementLinePArticleTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end