458 lines
19 KiB
Ruby
458 lines
19 KiB
Ruby
class PProduct < ApplicationRecord
|
|
has_many :p_product_p_normes, :dependent => :destroy
|
|
has_many :p_product_specs, :through => :p_product_p_normes
|
|
|
|
has_many :p_product_refs, :dependent => :destroy
|
|
accepts_nested_attributes_for :p_product_refs, allow_destroy: true
|
|
|
|
has_many :p_product_ingredients, :dependent => :destroy
|
|
accepts_nested_attributes_for :p_product_ingredients, allow_destroy: true
|
|
|
|
|
|
has_many :p_product_aromes, :dependent => :destroy
|
|
accepts_nested_attributes_for :p_product_aromes, allow_destroy: true
|
|
|
|
has_many :p_product_nutris, :dependent => :destroy
|
|
accepts_nested_attributes_for :p_product_nutris, allow_destroy: true
|
|
|
|
has_many :p_articles, through: :p_product_refs
|
|
|
|
# has_many :p_product_ref_specs, through: :p_product_refs
|
|
# accepts_nested_attributes_for :p_product_ref_specs
|
|
# # has_many :p_spec_types, through: :p_product_ref_specs
|
|
# has_many :p_spec_values, through: :p_product_ref_specs
|
|
# accepts_nested_attributes_for :p_spec_types, allow_destroy: true
|
|
# accepts_nested_attributes_for :p_spec_values, allow_destroy: true
|
|
|
|
|
|
has_many :p_product_images
|
|
|
|
belongs_to :p_customer
|
|
belongs_to :sorecop_cat
|
|
|
|
belongs_to :p_product_cat
|
|
belongs_to :s_brand
|
|
|
|
validates :name, :presence => true, exclusion: { in: ["--> Selectioner un produit <--"], message: "Selectioner un produit avant de valider" }
|
|
validates :code, :presence => true, :uniqueness => true, exclusion: { in: ["--> Indiquer un code produit <--"], message: "Indiquer un code produit avant de valider" }
|
|
|
|
has_many :tvable_tva_rates, :as => :tvable
|
|
has_many :tva_rates, :through => :tvable_tva_rates
|
|
|
|
|
|
has_many :p_product_p_product_sub_cats, :dependent => :destroy
|
|
|
|
has_many :p_product_sub_cats, :through => :p_product_p_product_sub_cats
|
|
|
|
has_many :p_product_p_customer_cats, :dependent => :destroy
|
|
|
|
has_many :p_customer_cats, :through => :p_product_p_customer_cats
|
|
|
|
has_many :p_product_origines
|
|
|
|
has_many :p_origines, :through => :p_product_origines
|
|
|
|
has_many :p_product_utilisations
|
|
|
|
has_many :p_utilisations, :through => :p_product_utilisations
|
|
|
|
|
|
acts_as_sorting :fields => {
|
|
:id => {:name => "ID"},
|
|
:code => {:name => "Code", :reorder => true},
|
|
:name => {:name => "Nom", :reorder => true},
|
|
:enabled => {:name => "Actif ?", :reorder => true, :format => :boolean},
|
|
:p_product_cat => {:name => "Catégorie", :reorder => false},
|
|
:s_brand => {:name => "Marque", :reorder => true, :sort_name => "s_brands.name", :member_label => :name},
|
|
|
|
:actions => {:name => "Actions", :reorder => true}
|
|
|
|
}
|
|
|
|
include PgSearch::Model
|
|
pg_search_scope :global_search,
|
|
against: [:name, :code],
|
|
associated_against: {
|
|
p_product_refs: [:cc_name, :ref],
|
|
s_brand: [ :code, :name ],
|
|
},
|
|
using: {
|
|
tsearch: { prefix: true }
|
|
}
|
|
|
|
before_validation do
|
|
if self.code.blank?
|
|
generate_code
|
|
end
|
|
end
|
|
|
|
|
|
def self.for_search(search)
|
|
PProduct.where("name LIKE ? or code LIKE ?", "%#{search}%", "%#{search}%").where(:enabled => true)
|
|
end
|
|
|
|
def self.convert_price_kg
|
|
PProduct.where(:price_calc => "Kg").all.each do |p_product|
|
|
weight = nil
|
|
|
|
p_product.p_product_refs.each do |p_product_ref|
|
|
if p_product_ref.weight.to_f != 0.0
|
|
weight = p_product_ref.weight
|
|
p_product_ref.ct_price_ht = weight * p_product_ref.ct_price_ht
|
|
|
|
p_product_ref.save
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
if weight
|
|
p_product.ct_purchase_price_ht = p_product.ct_purchase_price_ht*weight
|
|
end
|
|
|
|
p_product.save
|
|
|
|
end
|
|
end
|
|
|
|
after_create do
|
|
|
|
end
|
|
|
|
after_save do
|
|
self.p_product_refs.each do |ppr|
|
|
ppr.save
|
|
end
|
|
self.class.destroy_temp_p_product
|
|
end
|
|
|
|
def self.destroy_temp_p_product
|
|
temp_p_product = PProduct.find_by(name: "--> Selectioner un produit <--", code: "--> Indiquer un code produit <--")
|
|
if temp_p_product.present?
|
|
temp_p_product.destroy
|
|
end
|
|
end
|
|
|
|
def tva_rate(accounting_zone_id)
|
|
if r = self.tva_rates.where(:accounting_zone_id => accounting_zone_id).first
|
|
|
|
elsif self.p_product_cat and r = self.p_product_cat.tva_rates.where(:accounting_zone_id => accounting_zone_id).first
|
|
|
|
else
|
|
r = nil
|
|
|
|
end
|
|
|
|
return r
|
|
end
|
|
|
|
|
|
def csv_tva_rate
|
|
self.tva_rate(1).rate if self.tva_rate(1)
|
|
end
|
|
|
|
|
|
def csv_dluo
|
|
""
|
|
end
|
|
|
|
def csv_enabled
|
|
if self.enabled
|
|
"Oui"
|
|
else
|
|
"Non"
|
|
end
|
|
end
|
|
|
|
def csv_p_product_cat
|
|
self.p_product_cat.name if self.p_product_cat
|
|
end
|
|
|
|
def csv_p_customer_cats
|
|
self.p_customer_cats.map{ |p| p.name}.join(",")
|
|
end
|
|
|
|
def csv_s_brand
|
|
self.s_brand.name if self.s_brand
|
|
end
|
|
|
|
def default_image
|
|
self.p_product_images.order(:position).first
|
|
end
|
|
|
|
|
|
def generate_code
|
|
if !self.code
|
|
arr = []
|
|
brand = self.s_brand.code.to_s if self.s_brand
|
|
|
|
cat = self.p_product_cat.name.slice(0, 5).to_slug.upcase.to_s if self.p_product_cat
|
|
last_number = 1
|
|
|
|
arr << brand if brand.present?
|
|
arr << cat if cat.present?
|
|
arr << "%02d" % [last_number]
|
|
arr.prepend("PRODUCT") if arr.length < 2
|
|
code = arr.join('-')
|
|
|
|
while self.class.find_by(code: code)
|
|
arr = []
|
|
last_number += 1
|
|
arr << brand if brand.present?
|
|
arr << cat if cat.present?
|
|
arr << "%02d" % [last_number]
|
|
arr.prepend("PRODUCT") if arr.length < 2
|
|
code = arr.join('-')
|
|
end
|
|
self.code = code
|
|
end
|
|
end
|
|
|
|
|
|
acts_as_csv_import :fields => [
|
|
:identifiant,
|
|
:gencode,
|
|
:id,
|
|
:marque,
|
|
:famille,
|
|
:reference,
|
|
:modele,
|
|
:couleur,
|
|
:color,
|
|
:connectivite,
|
|
:sim,
|
|
:taille,
|
|
:capacite,
|
|
:infos_supp,
|
|
:reference_fabricant,
|
|
:etat,
|
|
:code_hs,
|
|
:indice_reparabilite,
|
|
:duree_dispo_pces_detachees,
|
|
:das_tete,
|
|
:das_corps,
|
|
:das_membre,
|
|
:poids,
|
|
:nb_pcs_colis,
|
|
:code_om,
|
|
:dtl,
|
|
:gbh_code_971,
|
|
:gbh_code_972,
|
|
:gbh_code_973,
|
|
:code_art,
|
|
:sorecop,
|
|
:pmp_hors_sorecop,
|
|
:target_hors_sorecop,
|
|
:frs,
|
|
:date,
|
|
:spec,
|
|
:dtl_targ,
|
|
:commentaires,
|
|
:com
|
|
]
|
|
|
|
def self.custom_csv_import(list, import_csv)
|
|
# ap "*********************************************************************************************************"
|
|
# ap "*********************************************************************************************************"
|
|
ap "*********************************************************************************************************"
|
|
# ap list.size
|
|
# ap list.class
|
|
# ap "*********************************************************************************************************"
|
|
# ap "*********************************************************************************************************"
|
|
# ap "*********************************************************************************************************"
|
|
# ap import_csv
|
|
# ap "*********************************************************************************************************"
|
|
# ap "*********************************************************************************************************"
|
|
# ap "*********************************************************************************************************"
|
|
soreco_cat_hash = {
|
|
"Smartphone" => "Smartphones & Téléphones mobiles",
|
|
"Mobile" => "Smartphones & Téléphones mobiles",
|
|
"Tablette" => "Tablettes média et tablette PC",
|
|
"MP4" => "Baladeur MP4",
|
|
"Clé USB" => "Clés USB",
|
|
"Carte Mémoire" => "Cartes mémoires",
|
|
"Boitier Multimédia" => "Décodeurs, téléviseurs, enregistreurs"
|
|
}
|
|
|
|
list.each do |row|
|
|
next if row["marque"].blank?
|
|
n = self.find_or_initialize_by(s_brand: SBrand.find_by(name: row["marque"]), name: row["reference"])
|
|
n.imported = true
|
|
n.sorecop_cat = SorecopCat.find_by(name: soreco_cat_hash[row["famille"]])
|
|
ref = n.p_product_refs.build
|
|
|
|
row.each do |key, value|
|
|
if value.present?
|
|
case key
|
|
when "identifiant"
|
|
ref.description = value if !value.blank?
|
|
when "gencode"
|
|
ref.genecode = value if !value.blank?
|
|
when "id"
|
|
|
|
when "marque"
|
|
n.s_brand = SBrand.find_or_create_by!(name: value)
|
|
|
|
when "famille"
|
|
n.p_product_cat = PProductCat.find_or_create_by!(name: value)
|
|
|
|
when "reference"
|
|
n.name = value if !value.blank?
|
|
|
|
when "modele"
|
|
ref.ct_sub_name = value if !value.blank?
|
|
|
|
when "couleur"
|
|
ref.p_product_color = PProductColor.find_or_create_by!(name: value)
|
|
|
|
when "color"
|
|
if ref.p_product_color.nil?
|
|
ref.p_product_color = PProductColor.find_or_create_by!(color: value)
|
|
end
|
|
when "connectivite"
|
|
arr = []
|
|
cellular = [ "5G", "3G", "3G+", "4G", "4G+", "2G", "wifi", "BT"]
|
|
video = ["4K","HD" ]
|
|
power = ["5W", "12W", "18W", "20W", "96W", "40W", "10W", "40W"]
|
|
mix = ["<87W/4K", "5G/4K", "wifi/BT" ]
|
|
geoloc = [ "GPS" ]
|
|
|
|
if mix.include?(value)
|
|
arr = value.split('/')
|
|
else
|
|
arr << value
|
|
end
|
|
|
|
arr.each do |value|
|
|
spec = nil
|
|
if cellular.include?(value)
|
|
spec = PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Connectivité"), p_spec_value: PSpecValue.find_or_create_by!(value: value))
|
|
elsif video.include?(value)
|
|
spec = PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Résolution"), p_spec_value: PSpecValue.find_or_create_by!(value: value.to_s))
|
|
elsif power.include?(value)
|
|
PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Puissance éléctrique"), p_spec_value: PSpecValue.find_or_create_by!(value: value.gsub('W', ''), unit: "W"))
|
|
elsif geoloc.include?(value)
|
|
spec = PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Géolocalisation"), p_spec_value: PSpecValue.find_or_create_by!(value: value))
|
|
else
|
|
spec = PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Autre"), p_spec_value: PSpecValue.find_or_create_by!(value: value))
|
|
end
|
|
import_csv.import_csv_elements << ImportCsvElement.new(:element => spec)
|
|
end
|
|
|
|
when "sim"
|
|
if ["DS", "SS"].include?(value)
|
|
PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Sim"), p_spec_value: PSpecValue.find_or_create_by!(value: value))
|
|
elsif value == "4G"
|
|
PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Connectivité"), p_spec_value: PSpecValue.find_or_create_by!(value: value))
|
|
end
|
|
|
|
when "taille"
|
|
float = value.to_s.match(/[^"\s]*/)
|
|
PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Taille"), p_spec_value: PSpecValue.find_or_create_by!(value: float.to_s, unit: '"'))
|
|
|
|
when "capacite"
|
|
unit = value.match(/\D+/)
|
|
num = value.match(/\d+/)
|
|
spec = PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Stockage"), p_spec_value: PSpecValue.find_or_create_by!(value: num.to_s, unit: unit.to_s))
|
|
import_csv.import_csv_elements << ImportCsvElement.new(:element => spec)
|
|
when "infos_supp"
|
|
spec = PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Autre"), p_spec_value: PSpecValue.find_or_create_by!(value: value))
|
|
import_csv.import_csv_elements << ImportCsvElement.new(:element => spec)
|
|
when "reference_fabricant"
|
|
ref.manufacturer_ref = value if !value.blank?
|
|
when "etat"
|
|
ref.used_state = value if !value.blank?
|
|
when "code_hs"
|
|
ref.i_code_hs = value if !value.blank?
|
|
when "indice_reparabilite"
|
|
ref.prepair_score = value if !value.blank?
|
|
when "duree_dispo_pces_detachees"
|
|
ref.part_delay = value if !value.blank?
|
|
when "das_tete"
|
|
ref.das_head = value if !value.blank?
|
|
when "das_corps"
|
|
ref.das_body = value if !value.blank?
|
|
when "das_membre"
|
|
ref.das_membre = value if !value.blank?
|
|
when "poids"
|
|
ref.weight = value if !value.blank?
|
|
when "nb_pcs_colis"
|
|
ref.nb_pcs_colis = value if !value.blank?
|
|
when "code_om"
|
|
ref.code_om = value if !value.blank?
|
|
when "gbh_code_971"
|
|
ref.gbh_code_971 = value if !value.blank?
|
|
when "gbh_code_972"
|
|
ref.gbh_code_972 = value if !value.blank?
|
|
when "gbh_code_973"
|
|
ref.gbh_code_973 = value if !value.blank?
|
|
when "code_art"
|
|
ref.code_art = value if !value.blank?
|
|
when "sorecop"
|
|
ref.p_product.sorecop_cat = SorecopCat.find_by(name: soreco_cat_hash[row["famille"]])
|
|
if ref.sorecop.kind_of?(String)
|
|
ref.ct_sorecop = value if !value.blank?
|
|
end
|
|
when "pmp_hors_sorecop"
|
|
ref.i_pmp_hors_sorecop = value if !value.blank?
|
|
when "target_hors_sorecop"
|
|
ref.i_target_hors_sorecop = value if !value.blank?
|
|
when "frs"
|
|
ref.p_fournisseur_id = PFournisseur.find_or_create_by!(name: value).id
|
|
when "spec"
|
|
spec = PProductRefSpec.create!(p_product_ref: ref, p_spec_type: PSpecType.find_by(name: "Version ROM"), p_spec_value: PSpecValue.find_or_create_by!(value: value))
|
|
import_csv.import_csv_elements << ImportCsvElement.new(:element => spec)
|
|
when "commentaires"
|
|
ref.i_comment = value if !value.blank?
|
|
|
|
# champs ignorés
|
|
when "date"
|
|
# colonne vide
|
|
when "dtl_targ"
|
|
when "dtl"
|
|
when "com"
|
|
else
|
|
eval "n.#{key} = value"
|
|
end
|
|
# if self.type_for_attribute(key) and self.type_for_attribute(key).type == :decimal
|
|
# eval "n.#{key} = value.to_s.gsub(' ', '').gsub(',', '.')"
|
|
# end
|
|
end
|
|
end
|
|
|
|
n.save!
|
|
import_csv.import_csv_elements << ImportCsvElement.new(:element => ref)
|
|
import_csv.import_csv_elements << ImportCsvElement.new(:element => n)
|
|
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ n §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap n
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ n.ref §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap ref
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ n.contacts §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap n.p_contacts
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ n.particulars §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap n.particulars
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ n.p_customer_ribs §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap n.p_customer_ribs
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ n.p_commercial §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap n.p_commercial
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
# ap "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§"
|
|
|
|
end
|
|
end
|
|
end
|