application_controller.rb 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. class ApplicationController < ActionController::Base
  2. # Prevent CSRF attacks by raising an exception.
  3. # For APIs, you may want to use :null_session instead.
  4. before_filter do
  5. resource = controller_path.singularize.tr('/', '_').to_sym
  6. method = "#{resource}_params"
  7. params[resource] &&= send(method) if respond_to?(method, true)
  8. end
  9. before_filter :set_pos_config
  10. around_filter :user_time_zone, if: :set_pos_config
  11. protect_from_forgery with: :exception
  12. ##--- Breadcrum_rails
  13. add_breadcrumb I18n.t("breadcrumbs.dashboard"), :root_path
  14. ##--- Restriccion para autentificacion
  15. before_action :authenticate_user!
  16. ##--- Notes boxes
  17. add_flash_types :success, :warning, :danger, :info
  18. ##--- Parametros permitidos para los usuarios
  19. before_action :configure_permitted_parameters, if: :devise_controller?
  20. ##--- Redireccionamiento para los permisos a modulos
  21. rescue_from CanCan::AccessDenied do |exception|
  22. redirect_to root_url, alert: exception.message
  23. end
  24. ##--- Funciones personalizadas
  25. def getcounties
  26. render json: SpmxCounty.where("state_id = ?", params[:state_id])
  27. end
  28. def find_products
  29. products =
  30. if params[:variants] == "true" && params[:query].include?(":")
  31. attributes = query_for_variants(params[:query])
  32. Product.name_sku_barcode_attribute_like(@product_name, attributes).limit(30).to_json(methods: [:small_img, :display_attributes, :display_sku_name_attributes])
  33. elsif params[:variants] == "true"
  34. Product.name_sku_barcode_like(params[:query]).limit(30).to_json(methods: [:small_img, :display_attributes, :display_sku_name_attributes])
  35. else
  36. Product.name_sku_barcode_like_sp(params[:query]).limit(30).to_json(methods: [:small_img, :display_attributes, :display_sku_name_attributes])
  37. end
  38. render json: products
  39. end
  40. def find
  41. query = params[:query]
  42. if query.include? ':' # search with attributes
  43. query_array = query.split(':')
  44. product_name = query_array[0]
  45. query_array.shift # delete the name of the product from the array to iterate the attributes
  46. attrs_query_string = ''
  47. query_array.each do |attribute|
  48. if attribute.present?
  49. attr_type = case attribute[0]
  50. when 'c'
  51. 'colors'
  52. when 't'
  53. 'sizes'
  54. when 'e'
  55. 'styles'
  56. end
  57. attribute[0] = "" # delete the attribute type character
  58. attrs_query_string.concat(" AND attributes_json::json->>'#{attr_type}' ilike '%#{attribute}%'")
  59. else
  60. next
  61. end
  62. end
  63. else
  64. product_name = query
  65. end
  66. 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])
  67. end
  68. def query_for_variants(query)
  69. product_query =
  70. if query.include? ':' # search with attributes
  71. query_array = query.split(':')
  72. @product_name = query_array[0]
  73. query_array.shift # delete the name of the product from the array to iterate the attributes
  74. attrs_query_string = ''
  75. query_array.each do |attribute|
  76. next if attribute.nil?
  77. attr_type =
  78. case attribute[0]
  79. when 'c'
  80. 'colors'
  81. when 't'
  82. 'sizes'
  83. when 'e'
  84. 'styles'
  85. end
  86. attribute[0] = "" # delete the attribute type character
  87. attrs_query_string.concat(" AND attributes_json::json->>'#{attr_type}' ilike '%#{attribute}%'")
  88. end
  89. attrs_query_string
  90. else
  91. query
  92. end
  93. product_query
  94. end
  95. # para special_prices
  96. def find_sp
  97. query = params[:query]
  98. product_name = query
  99. render json: Product.name_sku_barcode_like_sp(product_name).limit(30).to_json(methods: [:small_img])
  100. end
  101. def find_from_stock
  102. query = params[:query]
  103. location =
  104. if current_user.usertype == "S"
  105. Warehouse.find(current_user.warehouse_id).products
  106. else
  107. Pointsale.find(current_user.pointsale_id).products
  108. end
  109. attributes = query_for_variants(params[:query])
  110. consult =
  111. if query.include? ':'
  112. location.name_sku_barcode_attribute_like(@product_name, attributes)
  113. else
  114. location.name_sku_barcode_like(params[:query])
  115. end
  116. render json: consult.where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes])
  117. end
  118. def find_from_stock_by_pointsale
  119. if params[:pointsale_id].present?
  120. id = params[:pointsale_id][2, params[:pointsale_id].length]
  121. attributes = query_for_variants(params[:query])
  122. query = params[:query]
  123. location =
  124. if params[:pointsale_id].first == "P"
  125. Pointsale.find(id).products
  126. else
  127. Warehouse.find(id).products
  128. end
  129. consult =
  130. if query.include?(":")
  131. location.name_sku_barcode_attribute_like(@product_name, attributes)
  132. else
  133. location.name_sku_barcode_like(params[:query])
  134. end
  135. render json: consult.where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes])
  136. else
  137. render json: {}
  138. end
  139. end
  140. def get_subcategories
  141. render json: params[:category_id] != '0' ? Category.activos.where("parent_id = ?", params[:category_id]) : Category.activos.where('parent_id != 0')
  142. end
  143. def set_pos_config
  144. @pos_config = PosConfig.first
  145. end
  146. def user_time_zone(&block)
  147. Time.use_zone(@pos_config.time_zone, &block)
  148. end
  149. def delete_pre_sales
  150. PreSale.where(user_id: current_user.id).destroy_all
  151. respond_to do |format|
  152. format.json { head :no_content }
  153. end
  154. end
  155. def delete_pre_purchases
  156. PrePurchase.where(user_id: current_user.id).destroy_all
  157. # render head :no_content
  158. respond_to do |format|
  159. format.json { head :no_content }
  160. end
  161. end
  162. def delete_pre_transfers
  163. respond_to do |format|
  164. pre_transfers = PreTransfer.where(user_id: current_user.id)
  165. pre_transfers.each do |pre|
  166. # rubocop:disable Style/Next
  167. if pre.destroy
  168. 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)
  169. stock.stock += pre.quantity
  170. stock.save
  171. end
  172. # rubocop:enable Style/Next
  173. end
  174. format.json { head :ok }
  175. end
  176. end
  177. def get_max_product_id
  178. render json: Product.maximum(:id).to_i.next
  179. end
  180. def get_max_purchaseid_by_pointsale
  181. prefix = Pointsale.find(params[:pointsale_id]).prefix
  182. next_id = Purchase.where(pointsale_id: params[:pointsale_id]).count.next
  183. render json: "#{prefix}-C-#{next_id}"
  184. end
  185. def get_max_purchaseid_by_warehouse
  186. prefix = Warehouse.find(params[:warehouse_id]).prefix
  187. next_id = Purchase.where(warehouse_id: params[:warehouse_id]).count.next
  188. render json: "#{prefix}-C-#{next_id}"
  189. end
  190. def get_next_sale_code
  191. pointsale = OpenCashRegister.find(params[:open_cash_register_id]).cash_register.pointsale
  192. next_id = pointsale.sales.count.next
  193. render json: "#{pointsale.prefix}-V-#{next_id}"
  194. end
  195. def get_next_expense_code
  196. code =
  197. if current_user.usertype == "A" || current_user.usertype == "SS"
  198. next_id = Expense.where("expense_code ilike ?", '%ADM%').count.next
  199. "ADM-E-#{next_id}"
  200. else
  201. pointsale = OpenCashRegister.find(params[:open_cash_register_id]).cash_register.pointsale
  202. next_id = pointsale.expenses.count.next
  203. "#{pointsale.prefix}-E-#{next_id}"
  204. end
  205. render json: code
  206. end
  207. def products_by_category_pointsale
  208. products = Array.new
  209. products_by_line = Array.new
  210. category_id = params[:category_id]
  211. id = params[:pointsale_id][2, params[:pointsale_id].length]
  212. categories = Category.find(category_id).self_and_descendents
  213. categories.each do |category|
  214. products_by_line += category.products
  215. end
  216. if params[:pointsale_id].first == 'P'
  217. Pointsale.find(id).products.each do |p|
  218. if products_by_line.include?(p)
  219. products << p
  220. end
  221. end
  222. else
  223. Warehouse.find(id).products.each do |p|
  224. if products_by_line.include?(p)
  225. products << p
  226. end
  227. end
  228. end
  229. render json: products
  230. end
  231. ## ======= invoice methods =======
  232. def check_directorys(t, move_type)
  233. unless Dir.exist?(Rails.public_path.join("invoice", "cfdi")) # carpeta invoice
  234. Dir.mkdir(Rails.public_path.join("invoice", "cfdi"))
  235. end
  236. unless Dir.exist?(Rails.public_path.join("invoice/cfdi", t.strftime('%Y'))) # carpeta cfdi
  237. Dir.mkdir(Rails.public_path.join("invoice/cfdi", t.strftime("%Y")))
  238. end
  239. unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"))) # carpeta del año
  240. Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m")))
  241. end
  242. unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "xml")) # carpeta del mes
  243. Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}", "xml"))
  244. end
  245. unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "xml", move_type)) # carpeta de tipo de factura
  246. Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/xml", move_type))
  247. end
  248. unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "pdf")) # carpeta para pdf
  249. Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}", "pdf"))
  250. end
  251. unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "pdf", move_type))
  252. Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/pdf", move_type))
  253. end
  254. unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "qr"))
  255. Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}", "qr"))
  256. end
  257. unless Dir.exist?(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}", t.strftime("%m"), "qr", move_type))
  258. Dir.mkdir(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/qr", move_type))
  259. end
  260. end
  261. def check_stamper_status
  262. response = 500
  263. uri = URI(Rails.application.config.issuing['stamper_uri'])
  264. use_ssl = true
  265. http = Net::HTTP.new(uri.host, uri.port)
  266. http.use_ssl = use_ssl
  267. http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  268. http.start do
  269. req = Net::HTTP::Get.new("/")
  270. response = http.request(req)
  271. return response.code
  272. end
  273. rescue
  274. return 500
  275. end
  276. def create_invoice_qr(t, file_name, binary_qr, move_type)
  277. File.open(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/qr/#{move_type}", file_name), 'wb') do |file|
  278. binary_data = Base64.decode64(binary_qr)
  279. file << binary_data
  280. end
  281. end
  282. def create_xml_stamped(t, file_name, stamped_xml, move_type)
  283. File.open(Rails.public_path.join("invoice/cfdi/#{t.strftime('%Y')}/#{t.strftime('%m')}/xml/#{move_type}", file_name), 'w') do |file|
  284. file << stamped_xml << "\n"
  285. end
  286. end
  287. def get_attributes(created_at, amount, total, folio, payment_method_key, postal_code, serie, comprobante, pay_method)
  288. attributes = {
  289. "Version" => Rails.application.config.issuing['Version'].to_s,
  290. "Serie" => serie,
  291. "Folio" => folio,
  292. "Fecha" => created_at,
  293. "FormaPago" => payment_method_key,
  294. "SubTotal" => amount,
  295. "Moneda" => "MXN",
  296. "Total" => total,
  297. "TipoDeComprobante" => comprobante,
  298. "MetodoPago" => pay_method,
  299. "LugarExpedicion" => postal_code.to_s
  300. }
  301. end
  302. def get_namespaces(type)
  303. if type == "invoice" # factura
  304. namespaces = {
  305. "xmlns:tfd" => "http://www.sat.gob.mx/TimbreFiscalDigital",
  306. "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
  307. "xsi:schemaLocation" => "http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
  308. }
  309. elsif type == "complement" # complemento de pago
  310. namespaces = {
  311. "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
  312. "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"
  313. }
  314. end
  315. end
  316. def remove_invoice_files(uuid, file_id, url)
  317. unless url.blank?
  318. if File.exist?(Rails.root.join(url, "pdf", "#{uuid}_#{file_id}.pdf"))
  319. File.delete(Rails.root.join(url, "pdf", "#{uuid}_#{file_id}.pdf"))
  320. end
  321. if File.exist?(Rails.root.join(url, "xml", "#{uuid}_#{file_id}.xml"))
  322. File.delete(Rails.root.join(url, "xml", "#{uuid}_#{file_id}.xml"))
  323. end
  324. end
  325. end
  326. def remove_xml_origin(save_path)
  327. if File.exist?(save_path)
  328. File.delete(save_path)
  329. end
  330. end
  331. def send_invoice(mail_attributes)
  332. mail_response = InvoiceMailer.invoice_email_in(mail_attributes["name"], mail_attributes["email"], mail_attributes["attachments_name"], mail_attributes["attachments_url"]).deliver_now!
  333. if mail_response.status.to_i == 250
  334. return " Factura electrónica enviada exitosamente"
  335. else
  336. return " Error al enviar la factura electrónica"
  337. end
  338. rescue
  339. return " [Revisar configuración de servicio de email]"
  340. end
  341. ## /////// invoice methods ///////
  342. protected
  343. def configure_permitted_parameters
  344. devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:userid, :first_name, :last_name, :email, :password, :remember_me) }
  345. end
  346. def respond_modal_with(*args, &blk)
  347. options = args.extract_options!
  348. options[:responder] = ModalResponder
  349. respond_with(*args, options, &blk)
  350. end
  351. end