class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. before_filter do resource = controller_path.singularize.tr('/', '_').to_sym method = "#{resource}_params" params[resource] &&= send(method) if respond_to?(method, true) end before_filter :set_pos_config around_filter :user_time_zone, if: :set_pos_config protect_from_forgery with: :exception ##--- Breadcrum_rails add_breadcrumb I18n.t("breadcrumbs.dashboard"), :root_path ##--- Restriccion para autentificacion before_action :authenticate_user! ##--- Notes boxes add_flash_types :success, :warning, :danger, :info ##--- Parametros permitidos para los usuarios before_action :configure_permitted_parameters, if: :devise_controller? ##--- Redireccionamiento para los permisos a modulos rescue_from CanCan::AccessDenied do |exception| redirect_to root_url, alert: exception.message end ##--- Funciones personalizadas def getcounties render json: SpmxCounty.where("state_id = ?", params[:state_id]) end def find_products products = if params[:variants] == "true" && params[:query].include?(":") attributes = query_for_variants(params[:query]) Product.name_sku_barcode_attribute_like(@product_name, attributes).limit(30).to_json(methods: [:small_img, :display_attributes, :display_sku_name_attributes]) elsif params[:variants] == "true" Product.name_sku_barcode_like(params[:query]).limit(30).to_json(methods: [:small_img, :display_attributes, :display_sku_name_attributes]) else Product.name_sku_barcode_like_sp(params[:query]).limit(30).to_json(methods: [:small_img, :display_attributes, :display_sku_name_attributes]) end render json: products end def find query = params[:query] if query.include? ':' # search with attributes query_array = query.split(':') product_name = query_array[0] query_array.shift # delete the name of the product from the array to iterate the attributes attrs_query_string = '' query_array.each do |attribute| if attribute.present? attr_type = case attribute[0] when 'c' 'colors' when 't' 'sizes' when 'e' 'styles' end attribute[0] = "" # delete the attribute type character attrs_query_string.concat(" AND attributes_json::json->>'#{attr_type}' ilike '%#{attribute}%'") else next end end else product_name = query end render json: query.include?(":") ? Product.name_sku_barcode_attribute_like(product_name, attrs_query_string).limit(30).to_json(methods: [:small_img, :display_attributes]) : Product.name_sku_barcode_like(params[:query]).limit(30).to_json(methods: [:small_img, :display_attributes]) end def query_for_variants(query) product_query = if query.include? ':' # search with attributes query_array = query.split(':') @product_name = query_array[0] query_array.shift # delete the name of the product from the array to iterate the attributes attrs_query_string = '' query_array.each do |attribute| next if attribute.nil? attr_type = case attribute[0] when 'c' 'colors' when 't' 'sizes' when 'e' 'styles' end attribute[0] = "" # delete the attribute type character attrs_query_string.concat(" AND attributes_json::json->>'#{attr_type}' ilike '%#{attribute}%'") end attrs_query_string else query end product_query end # para special_prices def find_sp query = params[:query] product_name = query render json: Product.name_sku_barcode_like_sp(product_name).limit(30).to_json(methods: [:small_img]) end def find_from_stock query = params[:query] location = if current_user.usertype == "S" Warehouse.find(current_user.warehouse_id).products else Pointsale.find(current_user.pointsale_id).products end attributes = query_for_variants(params[:query]) consult = if query.include? ':' location.name_sku_barcode_attribute_like(@product_name, attributes) else location.name_sku_barcode_like(params[:query]) end render json: consult.where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes]) end def find_from_stock_by_pointsale if params[:pointsale_id].present? id = params[:pointsale_id][2, params[:pointsale_id].length] attributes = query_for_variants(params[:query]) query = params[:query] location = if params[:pointsale_id].first == "P" Pointsale.find(id).products else Warehouse.find(id).products end consult = if query.include?(":") location.name_sku_barcode_attribute_like(@product_name, attributes) else location.name_sku_barcode_like(params[:query]) end render json: consult.where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes]) else render json: {} end end def get_subcategories render json: params[:category_id] != '0' ? Category.activos.where("parent_id = ?", params[:category_id]) : Category.activos.where('parent_id != 0') end def set_pos_config @pos_config = PosConfig.first end def user_time_zone(&block) Time.use_zone(@pos_config.time_zone, &block) end def delete_pre_sales PreSale.where(user_id: current_user.id).destroy_all respond_to do |format| format.json { head :no_content } end end def delete_pre_purchases PrePurchase.where(user_id: current_user.id).destroy_all # render head :no_content respond_to do |format| format.json { head :no_content } end end def delete_pre_transfers respond_to do |format| pre_transfers = PreTransfer.where(user_id: current_user.id) pre_transfers.each do |pre| # rubocop:disable Style/Next if pre.destroy stock = pre.origin_is_pointsale == 1 ? AvailableProduct.find_by(pointsale_id: pre.origin_id, product_id: pre.product_id) : WarehouseStock.find_by(warehouse_id: pre.origin_id, product_id: pre.product_id) stock.stock += pre.quantity stock.save end # rubocop:enable Style/Next end format.json { head :ok } end end def get_max_product_id render json: Product.maximum(:id).to_i.next end def get_max_purchaseid_by_pointsale prefix = Pointsale.find(params[:pointsale_id]).prefix next_id = Purchase.where(pointsale_id: params[:pointsale_id]).count.next render json: "#{prefix}-C-#{next_id}" end def get_max_purchaseid_by_warehouse prefix = Warehouse.find(params[:warehouse_id]).prefix next_id = Purchase.where(warehouse_id: params[:warehouse_id]).count.next render json: "#{prefix}-C-#{next_id}" end def get_next_sale_code pointsale = OpenCashRegister.find(params[:open_cash_register_id]).cash_register.pointsale next_id = pointsale.sales.count.next render json: "#{pointsale.prefix}-V-#{next_id}" end def get_next_expense_code code = if current_user.usertype == "A" || current_user.usertype == "SS" next_id = Expense.where("expense_code ilike ?", '%ADM%').count.next "ADM-E-#{next_id}" else pointsale = OpenCashRegister.find(params[:open_cash_register_id]).cash_register.pointsale next_id = pointsale.expenses.count.next "#{pointsale.prefix}-E-#{next_id}" end render json: code end def products_by_category_pointsale products = Array.new products_by_line = Array.new category_id = params[:category_id] id = params[:pointsale_id][2, params[:pointsale_id].length] categories = Category.find(category_id).self_and_descendents categories.each do |category| products_by_line += category.products end if params[:pointsale_id].first == 'P' Pointsale.find(id).products.each do |p| if products_by_line.include?(p) products << p end end else Warehouse.find(id).products.each do |p| if products_by_line.include?(p) products << p end end end render json: products end ## ======= invoice methods ======= def check_directorys(t, move_type) unless Dir.exist?(Rails.public_path.join("invoice", "cfdi")) # carpeta invoice Dir.mkdir(Rails.public_path.join("invoice", "cfdi")) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi", t.strftime('%Y'))) # carpeta cfdi Dir.mkdir(Rails.public_path.join("invoice/cfdi", t.strftime("%Y"))) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"))) # carpeta del año Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"))) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "xml")) # carpeta del mes Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}", "xml")) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "xml", move_type)) # carpeta de tipo de factura Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/xml", move_type)) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "pdf")) # carpeta para pdf Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}", "pdf")) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "pdf", move_type)) Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/pdf", move_type)) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "qr")) Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}", "qr")) end unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "qr", move_type)) Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/qr", move_type)) end end def check_stamper_status response = 500 uri = URI(Rails.application.config.issuing['stamper_uri']) use_ssl = true http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = use_ssl http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.start do req = Net::HTTP::Get.new("/") response = http.request(req) return response.code end rescue return 500 end def create_invoice_qr(t, file_name, binary_qr, move_type) File.open(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/qr/#{move_type}", file_name), 'wb') do |file| binary_data = Base64.decode64(binary_qr) file << binary_data end end def create_xml_stamped(t, file_name, stamped_xml, move_type) File.open(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/xml/#{move_type}", file_name), 'w') do |file| file << stamped_xml << "\n" end end def get_attributes(created_at, amount, total, folio, payment_method_key, postal_code, serie, comprobante, pay_method) attributes = { "Version" => Rails.application.config.issuing['Version'].to_s, "Serie" => serie, "Folio" => folio, "Fecha" => created_at, "FormaPago" => payment_method_key, "SubTotal" => amount, "Moneda" => "MXN", "Total" => total, "TipoDeComprobante" => comprobante, "MetodoPago" => pay_method, "LugarExpedicion" => postal_code.to_s } end def get_namespaces(type) if type == "invoice" # factura namespaces = { "xmlns:tfd" => "http://www.sat.gob.mx/TimbreFiscalDigital", "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xsi:schemaLocation" => "http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd" } elsif type == "complement" # complemento de pago namespaces = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xsi:schemaLocation" => "http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd http://www.sat.gob.mx/Pagos http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd" } end end def remove_invoice_files(uuid, file_id, url) unless url.blank? if File.exist?(Rails.root.join(url, "pdf", "#{uuid}_#{file_id}.pdf")) File.delete(Rails.root.join(url, "pdf", "#{uuid}_#{file_id}.pdf")) end if File.exist?(Rails.root.join(url, "xml", "#{uuid}_#{file_id}.xml")) File.delete(Rails.root.join(url, "xml", "#{uuid}_#{file_id}.xml")) end end end def remove_xml_origin(save_path) if File.exist?(save_path) File.delete(save_path) end end def send_invoice(mail_attributes) mail_response = InvoiceMailer.invoice_email_in(mail_attributes["name"], mail_attributes["email"], mail_attributes["attachments_name"], mail_attributes["attachments_url"]).deliver_now! if mail_response.status.to_i == 250 return " Factura electrónica enviada exitosamente" else return " Error al enviar la factura electrónica" end rescue return " [Revisar configuración de servicio de email]" end ## /////// invoice methods /////// protected def configure_permitted_parameters devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:userid, :first_name, :last_name, :email, :password, :remember_me) } end def respond_modal_with(*args, &blk) options = args.extract_options! options[:responder] = ModalResponder respond_with(*args, options, &blk) end end