class PSheetLine < ApplicationRecord belongs_to :p_customer_sheet belongs_to :p_document has_one :p_customer, :through => :p_customer_sheet belongs_to :p_product belongs_to :p_tank has_one :particular_send, :through => :p_customer_sheet has_many :p_sheet_line_stocks, :dependent => :destroy has_many :p_ship_tour_truck_sheet_lines, :dependent => :destroy validates :custom_title, :presence => true, :if => :custom? validates :qte, :presence => true, :if => :not_validated? validates :price, :presence => true, :if => :not_validated? validates :ok_qte, :presence => true, :if => :validate_ok? validates :ok_price, :presence => true, :if => :validate_ok? validates :ok_at, :presence => true, :if => :validate_ok_at? validates :p_product, :presence => true, :if => :product_needed? #validates :p_tank, :presence => true, :if => :validate_tank? has_many :p_payments scope :oks, -> {where(:shiped => true).order("ok_at DESC")} scope :not_oks, -> {where(:shiped => false).order("ok_at DESC")} scope :between, lambda { |start, stop| after(start).before(stop) } scope :after, lambda { |date| where("(ok_at >= ?)", date ) } scope :before, lambda { |date| where("(ok_at <= ?)", date ) } def validate_ok_at? if self.element_label != "Avoir" and self.validate_ok? true else false end end def product_needed? if self.custom false else true end end def not_validated? if !self.price or !self.qte false else true end end def self.valid_sort ["qte", "particulars.cp", "particulars.city", "particulars.organisation, particulars.name, particulars.firstname", "p_products.name"] end def to_ship(p_ship_tour_truck) self.lock = true self.save self.generate_bl(p_ship_tour_truck.id) self.bl = true self.save self.p_customer_sheet.state = "livraison-en-cours" self.p_customer_sheet.save end after_save do self.p_customer_sheet.save if self.p_customer_sheet self.p_document.save if self.p_document end before_validation do if self.custom self.no_stock = true self.p_product_id = nil end if self.element_label == "Avoir" errors.add(:ok_price, "Vous devez indiquer un prix") if !self.ok_price? errors.add(:ok_qte, "Vous devez indiquer une quantité") if !self.ok_qte? errors.add(:ok_qte, "La quantité doit être négative") if self.ok_qte.to_f > 0 end if !self.imported self.price_tot = (self.qte.to_f * self.price.to_f).round(2) end if !self.imported self.ok_price_tot = (self.ok_qte.to_f * self.ok_price.to_f).round(2) end set_ttc() end def set_ttc if !self.arrondi or !self.ok_price_tot_ttc r = (self.price_tot * (self.tva + 1.0)) self.price_tot_ttc = r.round(2) r = (self.ok_price_tot * (self.tva + 1.0)) self.ok_price_tot_ttc = r.round(2) end end before_save do self.a_total_cost_ok = self.total_cost_ok if !self.imported if self.bl and self.ok self.shiped = true self.lock = true end end def cost_u_ok self.total_cost_ok / self.ok_qte.to_f end def marge_u_ok self.marge_ok / self.ok_qte.to_f end def marge_ok self.ok_price_tot - self.total_cost_ok end def total_cost_ok var = 0.0 self.p_sheet_line_stocks.each do |p_sheet_line_stock| var += p_sheet_line_stock.price_tot_ok end return var end def stock_is_ok if !self.stock_done if self.brut_product_needs_ok.size == self.p_sheet_line_stocks.group(:p_brut_product_id).length self.stock_done = true self.save end end end def update_stock if !self.externe and !self.stock_is_ok and self.shiped and !self.custom and !self.no_stock self.brut_product_needs_ok.each do |brut_index, brut_qte| p_brut_product = PBrutProduct.find(brut_index) qte_restante = brut_qte.to_f p_product_brut_stocks = PProductBrutStock.where(:p_brut_product_id => p_brut_product.id).where("externe = 0").where("qte_restant > 0.0").order("ok_at ASC").limit(100) if p_product_brut_stocks.sum(:qte_restant) >= qte_restante and self.p_sheet_line_stocks.where(:p_brut_product_id => p_brut_product.id).count == 0 i = 0 while qte_restante > 0.0 p_product_brut_stock = p_product_brut_stocks[i] if qte_restante <= p_product_brut_stock.qte_restant qte_to_affect = qte_restante else qte_to_affect = p_product_brut_stock.qte_restant end a = self.p_sheet_line_stocks.build(:ok_at => self.ok_at,:ok => true, :p_brut_product_id => p_brut_product.id, :qte_ok => qte_to_affect, :price_ok => p_product_brut_stock.ok_price, :p_product_brut_stock_id => p_product_brut_stock.id) p_product_brut_stock.qte_restant = p_product_brut_stock.qte_restant.to_f - qte_to_affect p_product_brut_stock.save qte_restante = qte_restante - qte_to_affect i += 1 end end end self.save self.stock_is_ok end end def brut_product_needs var = {} self.p_product.p_product_brut_products.each do |p_product_brut_product| var[p_product_brut_product.p_brut_product_id] = p_product_brut_product.qte.to_f * self.qte.to_f end return var end def brut_product_needs_ok var = {} self.p_product.p_product_brut_products.each do |p_product_brut_product| var[p_product_brut_product.p_brut_product_id] = p_product_brut_product.qte.to_f * self.ok_qte.to_f end return var end def generate_bl(p_ship_tour_truck_id = nil) self.p_customer_sheet.generate_bl(self.id, p_ship_tour_truck_id) end def ungenerate_bl self.p_customer_sheet.p_documents.where(:p_document_type_id => 5, :p_sheet_line_id => self.id).destroy_all end def validate_tank? if self.externe or self.custom or self.no_stock false self.p_tank = nil else true end end def validate_ok? if self.ok true else false end end def tva if self.p_document and self.p_document.created_at t = self.p_document.created_at elsif self.p_customer_sheet and self.p_customer_sheet.created_at t = self.p_customer_sheet.created_at else t = Time.now end t = t.beginning_of_day if t > Time.parse("2014-01-01 14:00:00").beginning_of_day 0.2 else 0.196 end end def ok_price_ttc (ok_price+(ok_price * tva)).round(5) end def price_ttc (price+(price * tva)).round(5) end def self.totals(sheet_lines) total = 0.0 total_ttc = 0.0 ok_total = 0.0 ok_total_ttc = 0.0 sheet_lines.each do |sheet_line| total += sheet_line.price_tot total_ttc += sheet_line.price_tot_ttc ok_total += sheet_line.ok_price_tot ok_total_ttc += sheet_line.ok_price_tot_ttc end return { :total => total, :total_ttc => total_ttc, :ok_total => ok_total, :ok_total_ttc => ok_total_ttc } end def decrement_stock if self.shiped self.p_sheet_line_stocks.each do |p_sheet_line_stock| new_p_sheet_line_stock = p_sheet_line_stock.dup new_p_sheet_line_stock.qte_ok = (new_p_sheet_line_stock.qte_ok * -1) new_p_sheet_line_stock.price_ok = (new_p_sheet_line_stock.price_ok) new_p_sheet_line_stock.decr = true new_p_sheet_line_stock.save new_p_sheet_line_stock.p_product_brut_stock.qte_restant = new_p_sheet_line_stock.p_product_brut_stock.ok_qte.to_f - new_p_sheet_line_stock.p_product_brut_stock.qte_used_calc new_p_sheet_line_stock.p_product_brut_stock.save self.save end self.stock_done = true self.decr = true self.save self.p_customer_sheet.save end end end