jose miguel 7 years atrás
parent
commit
0d4630665e
100 changed files with 3042 additions and 2971 deletions
  1. 180 170
      app/assets/javascripts/config.js
  2. 3 0
      app/assets/javascripts/errors.coffee
  3. 3 0
      app/assets/javascripts/reports.coffee
  4. 3 0
      app/assets/javascripts/supports.coffee
  5. 3 0
      app/assets/stylesheets/errors.scss
  6. 3 0
      app/assets/stylesheets/reports.scss
  7. 3 0
      app/assets/stylesheets/supports.scss
  8. 33 27
      app/controllers/application_controller.rb
  9. 18 2
      app/controllers/available_products_controller.rb
  10. 1 1
      app/controllers/cash_outs_controller.rb
  11. 29 31
      app/controllers/cash_registers_controller.rb
  12. 1 1
      app/controllers/commissions_controller.rb
  13. 1 1
      app/controllers/dashboard_controller.rb
  14. 14 0
      app/controllers/errors_controller.rb
  15. 6 5
      app/controllers/expenses_controller.rb
  16. 84 85
      app/controllers/expensesconcepts_controller.rb
  17. 2 12
      app/controllers/pointsales_controller.rb
  18. 15 13
      app/controllers/pos_configs_controller.rb
  19. 24 35
      app/controllers/product_wastes_controller.rb
  20. 5 1
      app/controllers/products_controller.rb
  21. 1 1
      app/controllers/products_returns_controller.rb
  22. 86 102
      app/controllers/purchases_controller.rb
  23. 30 0
      app/controllers/reports_controller.rb
  24. 39 37
      app/controllers/sales_controller.rb
  25. 39 41
      app/controllers/sellers_controller.rb
  26. 1 1
      app/controllers/special_prices_controller.rb
  27. 28 0
      app/controllers/supports_controller.rb
  28. 1 1
      app/controllers/transfers_controller.rb
  29. 30 8
      app/controllers/users_controller.rb
  30. 30 30
      app/controllers/warehouses_controller.rb
  31. 21 27
      app/datatables/available_products_datatable.rb
  32. 58 37
      app/datatables/products_datatable.rb
  33. 1 1
      app/datatables/stock_by_pointsale_datatable.rb
  34. 22 35
      app/datatables/stocks_datatable.rb
  35. 2 0
      app/helpers/errors_helper.rb
  36. 17 0
      app/helpers/pointsales_helper.rb
  37. 12 0
      app/helpers/purchases_helper.rb
  38. 6 0
      app/helpers/reports_helper.rb
  39. 2 0
      app/helpers/supports_helper.rb
  40. 23 0
      app/helpers/users_helper.rb
  41. 4 0
      app/mailers/application_mailer.rb
  42. 14 0
      app/mailers/support_mailer.rb
  43. 9 5
      app/models/ability.rb
  44. 0 2
      app/models/available_product.rb
  45. 16 24
      app/models/cash_out.rb
  46. 14 15
      app/models/cash_register.rb
  47. 20 20
      app/models/open_cash_register.rb
  48. 5 7
      app/models/pointsale.rb
  49. 5 5
      app/models/pos_config.rb
  50. 22 14
      app/models/product.rb
  51. 12 12
      app/models/product_waste.rb
  52. 1 1
      app/models/seller.rb
  53. 2 0
      app/models/user.rb
  54. 4 5
      app/views/available_products/_edit_price.html.erb
  55. 49 52
      app/views/available_products/_form.html.erb
  56. 83 89
      app/views/available_products/index.html.erb
  57. 23 20
      app/views/available_products/initial_stock.html.erb
  58. 27 30
      app/views/available_products/stock.html.erb
  59. 3 5
      app/views/available_products/stock_by_pointsale.html.erb
  60. 8 5
      app/views/cash_outs/_cash_out.html.erb
  61. 10 10
      app/views/cash_outs/index.html.erb
  62. 10 8
      app/views/cash_outs/opened_cash_registers.html.erb
  63. 185 187
      app/views/cash_outs/show.html.erb
  64. 35 57
      app/views/cash_registers/_form.html.erb
  65. 11 0
      app/views/cash_registers/create.js.erb
  66. 0 52
      app/views/cash_registers/edit.html.erb
  67. 14 0
      app/views/cash_registers/edit.js.erb
  68. 30 26
      app/views/cash_registers/index.html.erb
  69. 0 52
      app/views/cash_registers/new.html.erb
  70. 14 0
      app/views/cash_registers/new.js.erb
  71. 11 0
      app/views/cash_registers/update.js.erb
  72. 128 131
      app/views/commissions/_sellers_for_commissions.html.erb
  73. 58 72
      app/views/customers/customer_sales.html.erb
  74. 78 78
      app/views/dashboard/_dashboard_for_admin.html.erb
  75. 1 1
      app/views/dashboard/index.html.erb
  76. 25 0
      app/views/errors/internal_server_error.html.erb
  77. 11 0
      app/views/errors/not_found.html.erb
  78. 54 54
      app/views/expenses/_expenses_for_admin.html.erb
  79. 2 2
      app/views/expenses/_expenses_for_manager.html.erb
  80. 68 80
      app/views/expenses/_form.html.erb
  81. 3 3
      app/views/expenses/index.html.erb
  82. 66 67
      app/views/expensesconcepts/_form.html.erb
  83. 102 103
      app/views/expensesconcepts/index.html.erb
  84. 88 166
      app/views/layouts/application.html.erb
  85. 5 0
      app/views/layouts/mailer.html.erb
  86. 1 0
      app/views/layouts/mailer.text.erb
  87. 10 9
      app/views/pointsales/_assign_delete_prods.html.erb
  88. 36 26
      app/views/pointsales/_assign_products.html.erb
  89. 42 42
      app/views/pointsales/_form.html.erb
  90. 19 34
      app/views/pointsales/_index.html.erb
  91. 49 50
      app/views/pointsales/edit.html.erb
  92. 77 78
      app/views/pointsales/index.html.erb
  93. 73 59
      app/views/pos_configs/_form.html.erb
  94. 2 2
      app/views/pos_configs/index.html.erb
  95. 1 1
      app/views/pre_sales/_pre_sale.html.erb
  96. 8 10
      app/views/product_wastes/index.html.erb
  97. 418 442
      app/views/products/_form.html.erb
  98. 51 53
      app/views/products/_products_track_dtl.html.erb
  99. 45 0
      app/views/products/_products_track_purchases_dtl.html.erb
  100. 0 0
      app/views/products/edit.html.erb

+ 180 - 170
app/assets/javascripts/config.js

@@ -422,185 +422,178 @@ var TableWithCheckbox = function () {
 
 
 var tableWithCheckboxAjax = function () {
-		//var arrayForRows = [];
-		var initTableCheckboxAjax = function (tableClass, columns, order, extraParams, arrayForRows) {
-				var table = $(tableClass);
-
-				/* Table tools samples: https://www.datatables.net/release-datatables/extras/TableTools/ */
-				 $.fn.dataTableExt.oStdClasses.sFilterInput = "form-control input-xlarge input-inline";
-				/* Set tabletools buttons and button container */
-
-
-				var oTable = table.dataTable({
-					    "processing": true,
-					    "serverSide": true,
-						"ajax": {
-						    "url": $(tableClass).data('source'),
-						    "data": function ( d ) {
-						    	d.busqueda = $(tableClass).closest('.dataTables_wrapper').find('input[type="search"]').val();
-						        // son los parametros custom de cada tabla, se envia el obj.
-								for(var param in extraParams){
-							 		d[param] = extraParams[param];
-								}
-					    	}
-					    },
-					    "drawCallback": function( settings ) {
-					        arrayForRows.length = 0;
-					    },
-					    'columns': columns,
-			          	'columnDefs': [{
-				            'targets': 0,
-				            'searchable':false,
-				            'orderable':false,
-				            'className': 'dt-body-center',
-			             	'render': function (data, type, full, meta) {
-			                 	return '<input type="checkbox" name="id[]">';
-			             	}
-			          	}],
-						"language": {
-								"aria": {
-										"sortAscending": ": activate to sort column ascending",
-										"sortDescending": ": activate to sort column descending"
-								},
-								"sProcessing": "Cargando...",
-								"emptyTable": "No hay informacion en la tabla",
-								"info": "Mostrando del _START_ al _END_ de _TOTAL_ registros",
-								"infoEmpty": "No se encontraron coincidencias",
-								"infoFiltered": "(filtrado un total de _MAX_ registros)",
-								"lengthMenu": "Mostrar _MENU_ registros",
-								"search": "Buscar:",
-								"zeroRecords": "No se encontraron coincidencias",
-								"paginate": {
-		                            "sPrevious": "Ant",
-		                            "sNext": "Sig"
-		                        }
-						},
-						'order': [order, 'asc'],
-					      "rowCallback": function(row, data, dataIndex){
-					         // Get row ID
-					         var rowId = data[0];
-
-					         // If row ID is in the list of selected row IDs
-					         if($.inArray(rowId, arrayForRows) !== -1){
-					            $(row).find('input[type="checkbox"]').prop('checked', true);
-					            $(row).addClass('selected');
-					         }
-					      },
-						"lengthMenu": [
-								[20, 50, 75, 100,	-1],
-								[20, 50, 75, 100,	"Todos"] // change per page values here
-						],
-						// set the initial value
-						"pageLength": 20,
-						"dom": "<'row'<'col-md-6 col-sm-12'l><'col-md-6 col-sm-12'f>r><'table-scrollable't><'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>" // horizobtal scrollable datatable
-
-				});
-
-				var tableWrapper = $('.tableadvanced_wrapper'); // datatable creates the table wrapper by adding with id {your_table_jd}_wrapper
-
-				tableWrapper.find('.dataTables_length select').select2(); // initialize select2 dropdown
-
-
-				var table = $(tableClass).DataTable();
-					// Handle click on checkbox
-				   $(tableClass + ' tbody').on('click', 'input[type="checkbox"]', function(e){
-				      var $row = $(this).closest('tr');
-
-				      // Get row data
-				      var data = table.row($row).data();
-
-				      // Get row ID
-				      // var rowId = data[0];
-				      var rowId = $row.attr('id').substring($row.attr('id').indexOf('_') + 1, $row.attr('id').length);
-				      // Determine whether row ID is in the list of selected row IDs
-				      var index = $.inArray(rowId, arrayForRows);
-
-				      // If checkbox is checked and row ID is not in list of selected row IDs
-				      if(this.checked && index === -1){
-				         arrayForRows.push(rowId);
+	//var arrayForRows = [];
+	var initTableCheckboxAjax = function (tableClass, columns, order, extraParams, arrayForRows) {
+		var table = $(tableClass);
+
+		/* Table tools samples: https://www.datatables.net/release-datatables/extras/TableTools/ */
+		$.fn.dataTableExt.oStdClasses.sFilterInput = "form-control input-xlarge input-inline";
+		/* Set tabletools buttons and button container */
+		var oTable = table.dataTable({
+	    "processing": true,
+	    "serverSide": true,
+			"ajax": {
+		    "url": $(tableClass).data('source'),
+		    "data": function ( d ) {
+		    	d.busqueda = $(tableClass).closest('.dataTables_wrapper').find('input[type="search"]').val();
+		    	d.pointsale = $('#pointsale').val();
+	        // son los parametros custom de cada tabla, se envia el obj.
+					for(var param in extraParams){
+				 		d[param] = extraParams[param];
+					}
+	    	}
+	    },
+	    "drawCallback": function( settings ) {
+        arrayForRows.length = 0;
+	    },
+	    'columns': columns,
+    	'columnDefs': [{
+        'targets': 0,
+        'searchable':false,
+        'orderable':false,
+        'className': 'dt-body-center',
+       	'render': function (data, type, full, meta) {
+           	return '<input type="checkbox" name="id[]">';
+       	}
+    	}],
+			"language": {
+				"aria": {
+					"sortAscending": ": activate to sort column ascending",
+					"sortDescending": ": activate to sort column descending"
+				},
+				"sProcessing": "Cargando...",
+				"emptyTable": "No hay informacion en la tabla",
+				"info": "Mostrando del _START_ al _END_ de _TOTAL_ registros",
+				"infoEmpty": "No se encontraron coincidencias",
+				"infoFiltered": "(filtrado un total de _MAX_ registros)",
+				"lengthMenu": "Mostrar _MENU_ registros",
+				"search": "Buscar:",
+				"zeroRecords": "No se encontraron coincidencias",
+				"paginate": {
+          "sPrevious": "Ant",
+          "sNext": "Sig"
+        }
+			},
+			'order': [order, 'asc'],
+      "rowCallback": function(row, data, dataIndex) {
+        // Get row ID
+        var rowId = data[0];
+         // If row ID is in the list of selected row IDs
+          if($.inArray(rowId, arrayForRows) !== -1){
+            $(row).find('input[type="checkbox"]').prop('checked', true);
+            $(row).addClass('selected');
+          }
+	      },
+				"lengthMenu": [
+					[20, 50, 75, 100,	-1],
+					[20, 50, 75, 100,	"Todos"] // change per page values here
+				],
+				// set the initial value
+				"pageLength": 20,
+				"dom": "<'row'<'col-md-6 col-sm-12'l><'col-md-6 col-sm-12'f>r><'table-scrollable't><'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>" // horizobtal scrollable datatable
+		});
 
-				      // Otherwise, if checkbox is not checked and row ID is in list of selected row IDs
-				      } else if (!this.checked && index !== -1){
-				         arrayForRows.splice(index, 1);
-				      }
+		var tableWrapper = $('.tableadvanced_wrapper'); // datatable creates the table wrapper by adding with id {your_table_jd}_wrapper
+		tableWrapper.find('.dataTables_length select').select2(); // initialize select2 dropdown
+
+		var table = $(tableClass).DataTable();
+		// Handle click on checkbox
+	  $(tableClass + ' tbody').on('click', 'input[type="checkbox"]', function(e){
+      var $row = $(this).closest('tr');
+
+      // Get row data
+      var data = table.row($row).data();
+
+      // Get row ID
+      // var rowId = data[0];
+      var rowId = $row.attr('id').substring($row.attr('id').indexOf('_') + 1, $row.attr('id').length);
+      // Determine whether row ID is in the list of selected row IDs
+      var index = $.inArray(rowId, arrayForRows);
+
+      // If checkbox is checked and row ID is not in list of selected row IDs
+      if(this.checked && index === -1) {
+        arrayForRows.push(rowId);
+      	// Otherwise, if checkbox is not checked and row ID is in list of selected row IDs
+      } else if (!this.checked && index !== -1) {
+        arrayForRows.splice(index, 1);
+      }
 
-				      if(this.checked){
-				         $row.addClass('selected');
-				        //$row.css('background-color', '#34495E');
-				      } else {
-				        //$row.css('background-color', '#F9F9F9');
-				        $row.removeClass('selected');
-				      }
+      if(this.checked){
+        $row.addClass('selected');
+        //$row.css('background-color', '#34495E');
+      } else {
+        //$row.css('background-color', '#F9F9F9');
+        $row.removeClass('selected');
+      }
 
-				      // Update state of "Select all" control
-				      updateDataTableSelectAllCtrl(table);
+      // Update state of "Select all" control
+      updateDataTableSelectAllCtrl(table);
 
-				      // Prevent click event from propagating to parent
-				      e.stopPropagation();
-				   });
+      // Prevent click event from propagating to parent
+      e.stopPropagation();
+	  });
 
-				   // Handle click on table cells with checkboxes
-				   $(tableClass).on('click', 'tbody td, thead th:first-child', function(e){
-				      $(this).parent().find('input[type="checkbox"]').trigger('click');
-				   });
+	  // Handle click on table cells with checkboxes
+	  $(tableClass).on('click', 'tbody td, thead th:first-child', function(e){
+	    $(this).parent().find('input[type="checkbox"]').trigger('click');
+	  });
 
-				   // Handle click on "Select all" control
-				   $('thead input[name="select_all"]', table.table().container()).on('click', function(e){
-				      if(this.checked){
-				         $(tableClass + ' tbody input[type="checkbox"]:not(:checked)').trigger('click');
-				      } else {
-				         $(tableClass + ' tbody input[type="checkbox"]:checked').trigger('click');
-				      }
-
-				      // Prevent click event from propagating to parent
-				      e.stopPropagation();
-				   });
-
-				   // Handle table draw event
-				   table.on('draw', function(){
-				      // Update state of "Select all" control
-				      updateDataTableSelectAllCtrl(table);
-				   });
+	  // Handle click on "Select all" control
+	  $('thead input[name="select_all"]', table.table().container()).on('click', function(e){
+	    if(this.checked){
+        $(tableClass + ' tbody input[type="checkbox"]:not(:checked)').trigger('click');
+      } else {
+        $(tableClass + ' tbody input[type="checkbox"]:checked').trigger('click');
+      }
 
-				   function updateDataTableSelectAllCtrl(table){
-					   var $table             = table.table().node();
-					   var $chkbox_all        = $('tbody input[type="checkbox"]', $table);
-					   var $chkbox_checked    = $('tbody input[type="checkbox"]:checked', $table);
-					   var chkbox_select_all  = $('thead input[name="select_all"]', $table).get(0);
-
-					   // If none of the checkboxes are checked
-					   if($chkbox_checked.length === 0){
-					      chkbox_select_all.checked = false;
-					      if('indeterminate' in chkbox_select_all){
-					         chkbox_select_all.indeterminate = false;
-					      }
-
-					   // If all of the checkboxes are checked
-					   } else if ($chkbox_checked.length === $chkbox_all.length){
-					      chkbox_select_all.checked = true;
-					      if('indeterminate' in chkbox_select_all){
-					         chkbox_select_all.indeterminate = false;
-					      }
-
-					   // If some of the checkboxes are checked
-					   } else {
-					      chkbox_select_all.checked = true;
-					      if('indeterminate' in chkbox_select_all){
-					         chkbox_select_all.indeterminate = true;
-					      }
-					   }
-					}
+      // Prevent click event from propagating to parent
+      e.stopPropagation();
+	  });
+
+	  // Handle table draw event
+	  table.on('draw', function(){
+      // Update state of "Select all" control
+      updateDataTableSelectAllCtrl(table);
+	  });
+
+		function updateDataTableSelectAllCtrl(table){
+		  var $table = table.table().node();
+		  var $chkbox_all = $('tbody input[type="checkbox"]', $table);
+		  var $chkbox_checked = $('tbody input[type="checkbox"]:checked', $table);
+		  var chkbox_select_all = $('thead input[name="select_all"]', $table).get(0);
+
+		  // If none of the checkboxes are checked
+		  if($chkbox_checked.length === 0){
+	      chkbox_select_all.checked = false;
+	      if('indeterminate' in chkbox_select_all){
+	        chkbox_select_all.indeterminate = false;
+	      }
+
+		  	// If all of the checkboxes are checked
+		  } else if ($chkbox_checked.length === $chkbox_all.length){
+	      chkbox_select_all.checked = true;
+	      if('indeterminate' in chkbox_select_all){
+	        chkbox_select_all.indeterminate = false;
+	      }
+
+		  	// If some of the checkboxes are checked
+		  } else {
+	      chkbox_select_all.checked = true;
+	      if('indeterminate' in chkbox_select_all){
+	        chkbox_select_all.indeterminate = true;
+	      }
+		  }
 		}
-		return {
-				//main function to initiate the module
-				init: function (tableClass, columns, order, data, arrayForRows) {
-					if (!$().dataTable) {
-							return;
-					}
-					initTableCheckboxAjax(tableClass, columns, order, data, arrayForRows);
-
+	}
+	return {
+			//main function to initiate the module
+			init: function (tableClass, columns, order, data, arrayForRows) {
+				if (!$().dataTable) {
+					return;
 				}
-		};
+				initTableCheckboxAjax(tableClass, columns, order, data, arrayForRows);
+			}
+	};
 }();
 
 
@@ -1575,6 +1568,23 @@ $(document).on("page:change", function() {
 			});
 		}
 
+		if($('.select2-allow-clear-todas').get(0)){
+			$('select.select2-allow-clear-todas').select2({
+				allowClear: true,
+				placeholder: "Todas",
+				width: null,
+				placeholder: "Seleccione",
+				"language": {
+				   "noResults": function(){
+					   return "No se encontraron coincidencias";
+				   }
+				},
+				escapeMarkup: function (markup) {
+					return markup;
+				}
+			});
+		}
+
 		if($('#form').get(0) ){
 				FormValidation.init();
 		}

+ 3 - 0
app/assets/javascripts/errors.coffee

@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/

+ 3 - 0
app/assets/javascripts/reports.coffee

@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/

+ 3 - 0
app/assets/javascripts/supports.coffee

@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/

+ 3 - 0
app/assets/stylesheets/errors.scss

@@ -0,0 +1,3 @@
+// Place all the styles related to the errors controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/

+ 3 - 0
app/assets/stylesheets/reports.scss

@@ -0,0 +1,3 @@
+// Place all the styles related to the reports controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/

+ 3 - 0
app/assets/stylesheets/supports.scss

@@ -0,0 +1,3 @@
+// Place all the styles related to the supports controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/

+ 33 - 27
app/controllers/application_controller.rb

@@ -75,36 +75,40 @@ class ApplicationController < ActionController::Base
 
   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
+
     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
+        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
+      consult = location.name_sku_barcode_attribute_like(product_name, attrs_query_string)
     else
       product_name = query
+      consult = location.name_sku_barcode_like(params[:query])
     end
 
-    if current_user.usertype == 'S'
-      render json: query.include?(":") ? Warehouse.find(current_user.warehouse_id).products.name_sku_barcode_attribute_like(product_name, attrs_query_string).where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes]) : Warehouse.find(current_user.warehouse_id).products.name_sku_barcode_like(params[:query]).where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes])
-    else
-      render json: query.include?(":") ? Pointsale.find(current_user.pointsale_id).products.name_sku_barcode_attribute_like(product_name, attrs_query_string).where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes]) : Pointsale.find(current_user.pointsale_id).products.name_sku_barcode_like(params[:query]).where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes])
-    end
+    render json: consult.where("stock > 0").limit(30).to_json(methods: [:small_img, :display_attributes])
   end
 
   # rubocop:disable Metrics/BlockNesting
@@ -216,14 +220,16 @@ class ApplicationController < ActionController::Base
   end
 
   def get_next_expense_code
-    if current_user.usertype == 'A'
-      next_id = Expense.where("expense_code ilike ?", '%ADM%').count.next
-      render json: "ADM-E-#{next_id}"
-    else
-      pointsale = OpenCashRegister.find(params[:open_cash_register_id]).cash_register.pointsale
-      next_id = pointsale.expenses.count.next
-      render json: "#{pointsale.prefix}-E-#{next_id}"
-    end
+    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

+ 18 - 2
app/controllers/available_products_controller.rb

@@ -6,7 +6,15 @@ class AvailableProductsController < ApplicationController
     @showcolumns = "minMax"
     # se utiliza para mandarle al datatable el numero de columnas y en que orden se deben de acomodar
     @column_definition = [{ "data": "0" }, { "data": "1" }, { "data": "2" }, { "data": "3" }, { "data": "4" }, { "data": "5" }, { "data": "6" }, { "data": "7" }].to_json
-    @location_id = current_user.pointsale_id.present? ? current_user.pointsale_id : current_user.warehouse_id
+    @location_id =
+      if current_user.usertype == "G"
+        current_user.pointsale_id
+      elsif current_user.usertype == "S"
+        current_user.warehouse_id
+      else
+        @pointsales = Pointsale.activos
+        @pointsales.first.id
+      end
     respond_to do |format|
       format.html
       format.json { render json: StocksDatatable.new(view_context, current_user, @showcolumns) }
@@ -15,7 +23,15 @@ class AvailableProductsController < ApplicationController
 
   def initial_stock
     @showcolumns = "initial"
-    @location_id = current_user.pointsale_id.present? ? current_user.pointsale_id : current_user.warehouse_id
+    @location_id =
+      if current_user.usertype == "G"
+        current_user.pointsale_id
+      elsif current_user.usertype == "S"
+        current_user.warehouse_id
+      else
+        @pointsales = Pointsale.activos
+        @pointsales.first.id
+      end
     # se utiliza para mandarle al datatable el numero de columnas y en que orden se deben de acomodar
     @column_definition = [{ "data": "0" }, { "data": "1" }, { "data": "2" }, { "data": "3" }, { "data": "4" }, { "data": "5" }, { "data": "6" }].to_json
 

+ 1 - 1
app/controllers/cash_outs_controller.rb

@@ -15,7 +15,7 @@ class CashOutsController < ApplicationController
   # GET /cash_outs.json
   def index
     case current_user.usertype
-    when "A"
+    when "A", "SS"
       @cash_outs = CashOut.all.includes(:open_cash_register, :user, :received_by).order('cash_outs.created_at desc')
     when "G"
       @cash_outs = Pointsale.find(current_user.pointsale_id).cash_outs.includes(:open_cash_register, :user, :received_by).order('cash_outs.created_at desc')

+ 29 - 31
app/controllers/cash_registers_controller.rb

@@ -4,9 +4,9 @@ class CashRegistersController < ApplicationController
 
   ##--- Breadcrum_rails
   add_breadcrumb I18n.t("breadcrumbs." + controller_name), :cash_registers_path
-  add_breadcrumb "Nueva Caja registradora " , :new_cash_register_path, only: :new
-  add_breadcrumb "Detalle de la Caja registradora "  , :cash_register_path, only: :show
-  add_breadcrumb "Editar Caja registradora "  , :edit_cash_register_path, only: :edit
+  add_breadcrumb "Nueva Caja registradora ", :new_cash_register_path, only: :new
+  add_breadcrumb "Detalle de la Caja registradora ", :cash_register_path, only: :show
+  add_breadcrumb "Editar Caja registradora ", :edit_cash_register_path, only: :edit
 
   before_action :set_cash_register, only: [:show, :edit, :update, :destroy]
 
@@ -15,7 +15,7 @@ class CashRegistersController < ApplicationController
   # GET /cash_registers
   # GET /cash_registers.json
   def index
-    if current_user.usertype == 'A'
+    if current_user.usertype == "A" || current_user.usertype == "SS"
       @cash_registers = CashRegister.vigentes.includes(:pointsale)
     else
       @cash_registers = CashRegister.includes(:pointsale).where(:pointsale_id => current_user.pointsale_id ).vigentes
@@ -24,8 +24,7 @@ class CashRegistersController < ApplicationController
 
   # GET /cash_registers/1
   # GET /cash_registers/1.json
-  def show
-  end
+  def show; end
 
   # GET /cash_registers/new
   def new
@@ -33,8 +32,7 @@ class CashRegistersController < ApplicationController
   end
 
   # GET /cash_registers/1/edit
-  def edit
-  end
+  def edit; end
 
   # POST /cash_registers
   # POST /cash_registers.json
@@ -43,10 +41,11 @@ class CashRegistersController < ApplicationController
     @cash_register.pointsale_id = @current_user.pointsale_id
     respond_to do |format|
       if @cash_register.save
-          format.html { redirect_to cash_registers_url, success: "La caja " + @cash_register.name + " fue registrada." }
-        format.json { render :show, status: :created, location: @cash_register }
+        format.html { redirect_to cash_registers_url, success: "La caja " + @cash_register.name + " fue registrada." }
+        format.js
       else
         format.html { render :new }
+        format.js
         format.json { render json: @cash_register.errors, status: :unprocessable_entity }
       end
     end
@@ -56,31 +55,30 @@ class CashRegistersController < ApplicationController
   # PATCH/PUT /cash_registers/1.json
   def update
     respond_to do |format|
-      cash_register_opened = OpenCashRegister.where(:cash_register_id => @cash_register.id, :status => 0).any?
-
+      cash_register_opened = OpenCashRegister.where(cash_register_id: @cash_register.id, status: 0).any?
       if cash_register_opened == true && params[:cash_register][:status] == 'inactive'
         @cash_register.errors.add(:status, "No se puede desactivar una caja abierta.")
         format.html { render :edit }
+        format.js
         format.json { render json: @cash_register.errors, status: :unprocessable_entity }
       else
         @cash_register.update(cash_register_params)
-        format.html { redirect_to cash_registers_url,   success: "La caja " + @cash_register.name + " fue modificada." }
-        format.json { render :show, status: :ok, location: @cash_register }
+        format.js
       end
     end
   end
 
   def update_status
       cash_register = CashRegister.find(params[:cash_register_id])
-      puts cash_register.active?
-      if cash_register.active?
-        cash_register.status = 2
-      elsif cash_register.inactive?
-        cash_register.status = 1
-      end
+      cash_register.status =
+        if cash_register.active?
+          2
+        elsif cash_register.inactive?
+          1
+        end
       respond_to do |format|
-        if cash_register.save(:validate => false)
-            format.html { redirect_to cash_registers_url, warning: "La caja registradora " + cash_register.name + " fue "+ (cash_register.active? ? "activada" : "desactivada")+"." }
+        if cash_register.save(validate: false)
+          format.html { redirect_to cash_registers_url, warning: "La caja registradora " + cash_register.name + " fue " + (cash_register.active? ? "activada" : "desactivada") + "." }
           # format.json { render :show, status: :ok, location: @pointsale }
           format.json { head :no_content }
         else
@@ -106,7 +104,7 @@ class CashRegistersController < ApplicationController
           format.html { redirect_to cash_registers_url,  warning: "La caja " + @cash_register.name + " no se puede eliminar por ser la principal." }
           format.json { render json: @cash_register.errors, status: :unprocessable_entity }
         else
-          @cash_register.update_attributes(:status => 0)
+          @cash_register.update_attributes(status: 0)
           format.html { redirect_to cash_registers_url,  warning: "La caja " + @cash_register.name + " fue eliminada." }
           format.json { head :no_content }
         end
@@ -120,13 +118,13 @@ class CashRegistersController < ApplicationController
   end
 
   private
-    # Use callbacks to share common setup or constraints between actions.
-    def set_cash_register
-      @cash_register = CashRegister.find(params[:id])
-    end
+  # Use callbacks to share common setup or constraints between actions.
+  def set_cash_register
+    @cash_register = CashRegister.find(params[:id])
+  end
 
-    # Never trust parameters from the scary internet, only allow the white list through.
-    def cash_register_params
-      params.require(:cash_register).permit(:name, :description, :pointsale_id, :status)
-    end
+  # Never trust parameters from the scary internet, only allow the white list through.
+  def cash_register_params
+    params.require(:cash_register).permit(:name, :description, :pointsale_id, :status)
+  end
 end

+ 1 - 1
app/controllers/commissions_controller.rb

@@ -11,7 +11,7 @@ class CommissionsController < ApplicationController
   # GET /commissions
   # GET /commissions.json
   def index
-    @commissions = current_user.usertype == 'A' ? Commission.all.includes(:pointsale, :user).order('created_at desc') : Commission.includes(:pointsale, :user).where(pointsale_id: current_user.pointsale_id).order('created_at desc')
+    @commissions = current_user.usertype == "A" || current_user.usertype == "SS" ? Commission.all.includes(:pointsale, :user).order('created_at desc') : Commission.includes(:pointsale, :user).where(pointsale_id: current_user.pointsale_id).order('created_at desc')
   end
 
   # GET /commissions/1

+ 1 - 1
app/controllers/dashboard_controller.rb

@@ -1,7 +1,7 @@
 class DashboardController < ApplicationController
   def index
     @open_cash = false
-    if current_user.usertype == 'A'
+    if current_user.usertype == "A" || current_user.usertype == "SS"
       # obtener ingresos por punto de venta
       @incomings = ActionController::Base.helpers.sanitize(CashRegistersMove.incomings_per_period('day'))
       # obtener ranking de productos y prepararlo para mandarlo al view

+ 14 - 0
app/controllers/errors_controller.rb

@@ -0,0 +1,14 @@
+class ErrorsController < ApplicationController
+  def not_found
+    render(status: 404)
+  end
+
+  def internal_server_error
+    render(status: 500)
+  end
+
+  def show
+    status = params[:code] || 500
+    render status.to_s, status: status
+  end
+end

+ 6 - 5
app/controllers/expenses_controller.rb

@@ -14,7 +14,7 @@ class ExpensesController < ApplicationController
   # GET /expenses.json
   def index
     case current_user.usertype
-    when "A"
+    when "A", "SS"
       @from_pointsale = Expense.where.not(open_cash_register_id: nil).includes(:expensesconcept).order(" id DESC ")
       @general_expenses = Expense.where(open_cash_register_id: nil).includes(:expensesconcept).order(" id DESC ")
     when "G"
@@ -50,7 +50,7 @@ class ExpensesController < ApplicationController
       @concept_purchase_payment = Expensesconcept.find_by(expense_from_purchase: 1)
       @expense.status = :active
 
-      if current_user.usertype == "A"
+      if current_user.usertype == "A" || current_user.usertype == "SS"
         @expense.skip_open_cash_validation = true
         @expense.skip_open_cash_has_money = true
       else
@@ -67,7 +67,7 @@ class ExpensesController < ApplicationController
           end
         end
         # movimiento de efectivo
-        if current_user.usertype != "A"
+        if current_user.usertype != "A" || current_user.usertype != "SS"
           move = CashRegistersMove.new
           move.skip_received_validation = true
           move.expense_id = @expense.id
@@ -110,7 +110,7 @@ class ExpensesController < ApplicationController
   # DELETE /expenses/1.json
   def destroy
     respond_to do |format|
-      if current_user.usertype == 'A'
+      if current_user.usertype == "A" || current_user.usertype == "SS"
         @expense.skip_open_cash_validation = true
       end
 
@@ -129,7 +129,8 @@ class ExpensesController < ApplicationController
 
   def set_data
     @is_cashier = false
-    if current_user.usertype != "A"
+
+    if current_user.usertype != "A" && current_user.usertype != "SS"
       @expenses_concepts = Array.new
       Expensesconcept.where("status = 1 and allpoints = 'true'").each do |expense|
         @expenses_concepts << expense

+ 84 - 85
app/controllers/expensesconcepts_controller.rb

@@ -1,26 +1,26 @@
 class ExpensesconceptsController < ApplicationController
-	##--- Abilities
-	load_and_authorize_resource
+  ##--- Abilities
+  load_and_authorize_resource
 
-	##--- Breadcrum_rails
-	add_breadcrumb I18n.t("breadcrumbs." + controller_name), :expensesconcepts_path
-	add_breadcrumb "Nuevo Concepto de egreso" , :new_expensesconcept_path, only: :new
-	add_breadcrumb "Detalle del Concepto de egreso" , :expensesconcept_path, only: :show
-	add_breadcrumb "Editar Concepto de egreso" , :edit_expensesconcept_path, only: :edit
+  ##--- Breadcrum_rails
+  add_breadcrumb I18n.t("breadcrumbs." + controller_name), :expensesconcepts_path
+  add_breadcrumb "Nuevo Concepto de egreso", :new_expensesconcept_path, only: :new
+  add_breadcrumb "Detalle del Concepto de egreso", :expensesconcept_path, only: :show
+  add_breadcrumb "Editar Concepto de egreso", :edit_expensesconcept_path, only: :edit
 
-	before_action :set_expensesconcept, only: [:show, :edit, :update, :destroy]
-	before_action :get_filters, only: [:index, :show, :edit, :new]
-	# before_action :get_pointsales, only: [:create, :update]
+  before_action :set_expensesconcept, only: [:show, :edit, :update, :destroy]
+  before_action :get_filters, only: [:index, :show, :edit, :new]
+  # before_action :get_pointsales, only: [:create, :update]
 
-	# GET /expensesconcepts
-	# GET /expensesconcepts.json
-	def index
-    @concept_purchase_payment = Expensesconcept.find_by(:expense_from_purchase => 1)
-    if current_user.usertype == 'A'
+  # GET /expensesconcepts
+  # GET /expensesconcepts.json
+  def index
+    @concept_purchase_payment = Expensesconcept.find_by(expense_from_purchase: 1)
+    if current_user.usertype == "A" || current_user.usertype == "SS"
       @expensesconcepts = Expensesconcept.vigentes
     else
       @expensesconcepts = Array.new
-      Expensesconcept.where("status = 1 and allpoints = 'true'").each do |expense|
+      Expensesconcept.where(status: 1, allpoints: true).each do |expense|
         @expensesconcepts << expense
       end
 
@@ -31,7 +31,6 @@ class ExpensesconceptsController < ApplicationController
     end
   end
 
-
   # GET /expensesconcepts/new
   def new
     @expensesconcept = Expensesconcept.new
@@ -39,81 +38,81 @@ class ExpensesconceptsController < ApplicationController
 
   def create
     @expensesconcept = Expensesconcept.new(expensesconcept_params)
-		respond_to do |format|
-			@expensesconcept.audit_comment = "Concepto de egreso #{@expensesconcept.name} creado."
-			if @expensesconcept.save
-				# @expensesconcept.pointsales = @pointsales
-				format.html { redirect_to expensesconcepts_url, success: 'El concepto ' + @expensesconcept.name + ' fue creado.' }
-				format.json { render :show, status: :created, location: @expensesconcept }
-			else
-				format.html { render :new }
-				format.json { render json: @expensesconcept.errors, status: :unprocessable_entity }
-			end
-		end
-	end
+    respond_to do |format|
+      @expensesconcept.audit_comment = "Concepto de egreso #{@expensesconcept.name} creado."
+      if @expensesconcept.save
+        # @expensesconcept.pointsales = @pointsales
+        format.html { redirect_to expensesconcepts_url, success: 'El concepto ' + @expensesconcept.name + ' fue creado.' }
+        format.json { render :show, status: :created, location: @expensesconcept }
+      else
+        format.html { render :new }
+        format.json { render json: @expensesconcept.errors, status: :unprocessable_entity }
+      end
+    end
+  end
 
-	# PATCH/PUT /expensesconcepts/1
-	# PATCH/PUT /expensesconcepts/1.json
-	def update
-		respond_to do |format|
-			@expensesconcept.audit_comment = "Concepto de egreso #{@expensesconcept.name} modificado."
-			if @expensesconcept.update(expensesconcept_params)
+  # PATCH/PUT /expensesconcepts/1
+  # PATCH/PUT /expensesconcepts/1.json
+  def update
+    respond_to do |format|
+      @expensesconcept.audit_comment = "Concepto de egreso #{@expensesconcept.name} modificado."
+      if @expensesconcept.update(expensesconcept_params)
 
-				# @expensesconcept.pointsales = @pointsales
-				format.html { redirect_to expensesconcepts_url, success: 'El concepto ' + @expensesconcept.name + ' fue modificado.' }
-					format.json { render :show, status: :ok, location: @expensesconcept }
-			else
-				format.html { render :edit }
-				format.json { render json: @expensesconcept.errors, status: :unprocessable_entity }
-			end
-		end
-	end
+        # @expensesconcept.pointsales = @pointsales
+        format.html { redirect_to expensesconcepts_url, success: 'El concepto ' + @expensesconcept.name + ' fue modificado.' }
+        format.json { render :show, status: :ok, location: @expensesconcept }
+      else
+        format.html { render :edit }
+        format.json { render json: @expensesconcept.errors, status: :unprocessable_entity }
+      end
+    end
+  end
 
-	# DELETE /expensesconcepts/1
-	# DELETE /expensesconcepts/1.json
-	def destroy
-		#@expensesconcept.destroy
-		respond_to do |format|
-			@expensesconcept.audit_comment = "Concepto de egreso #{@expensesconcept.name} eliminado."
-			if @expensesconcept.update_attributes(:status => 0)
-						format.html { redirect_to expensesconcepts_url, warning: "El concepto " + @expensesconcept.name + " fue eliminado." }
-						format.json { head :no_content }
-			else
-				format.html { render :edit }
-				format.json { render json: @expensesconcept.errors, status: :unprocessable_entity }
-			end
-		end
-	end
+  # DELETE /expensesconcepts/1
+  # DELETE /expensesconcepts/1.json
+  def destroy
+    respond_to do |format|
+      @expensesconcept.audit_comment = "Concepto de egreso #{@expensesconcept.name} eliminado."
+      if @expensesconcept.update_attributes(status: 0)
+        format.html { redirect_to expensesconcepts_url, warning: "El concepto " + @expensesconcept.name + " fue eliminado." }
+        format.json { head :no_content }
+      else
+        format.html { render :edit }
+        format.json { render json: @expensesconcept.errors, status: :unprocessable_entity }
+      end
+    end
+  end
 
   private
-    # Use callbacks to share common setup or constraints between actions.
-    def set_expensesconcept
-      @expensesconcept = Expensesconcept.find(params[:id])
-    end
 
-    # Never trust parameters from the scary internet, only allow the white list through.
-    def expensesconcept_params
-      params.require(:expensesconcept).permit(:name, :description, :allpoints, :status, :pointsale_ids => [])
-    end
+  # Use callbacks to share common setup or constraints between actions.
+  def set_expensesconcept
+    @expensesconcept = Expensesconcept.find(params[:id])
+  end
 
-    def get_filters
-			if params[:current_page].blank?
-				@current_page = 1
-			else
-				@current_page = params[:current_page]
-			end
-			@filter = params[:filter]
-		end
+  # Never trust parameters from the scary internet, only allow the white list through.
+  def expensesconcept_params
+    params.require(:expensesconcept).permit(:name, :description, :allpoints, :status, pointsale_ids: [])
+  end
 
-    def get_pointsales
-        unless params[:expensesconcept][:pointsale_ids].nil? && params[:expensesconcept][:pointsale_ids].empty?
-            ## Issue arreglo primer elemento en blanco ...
-            params[:expensesconcept][:pointsale_ids] = params[:expensesconcept][:pointsale_ids].delete_if{ |x| x.empty? }
-            @pointsales = params[:expensesconcept][:pointsale_ids].map do |k|
-                Pointsale.find(k)
-            end
-        else
-            @pointsales = []
-        end
+  def get_filters
+    @current_page =
+      if params[:current_page].blank?
+        1
+      else
+        params[:current_page]
+      end
+    @filter = params[:filter]
+  end
+
+  def get_pointsales
+    @pointsales = []
+    unless params[:expensesconcept][:pointsale_ids].nil? && params[:expensesconcept][:pointsale_ids].empty?
+      ## Issue arreglo primer elemento en blanco ...
+      params[:expensesconcept][:pointsale_ids] = params[:expensesconcept][:pointsale_ids].delete_if(&:empty?)
+      @pointsales = params[:expensesconcept][:pointsale_ids].map do |k|
+        Pointsale.find(k)
+      end
     end
+  end
 end

+ 2 - 12
app/controllers/pointsales_controller.rb

@@ -50,12 +50,7 @@ class PointsalesController < ApplicationController
     respond_to do |format|
       if @pointsale.save
         @pointsale.users.first.pointsale_id = @pointsale.id
-        main_cash_register = CashRegister.new
-        main_cash_register.name = @pointsale.name + " Principal"
-        main_cash_register.description = "Caja registradora principal"
-        main_cash_register.pointsale_id = @pointsale.id
-        main_cash_register.main = 'yes'
-        main_cash_register.status = 'active'
+        main_cash_register = CashRegister.new(name: "#{@pointsale.name} Principal", description: "Caja registradora principal", pointsale_id: @pointsale.id, main: 'yes', status: 'active')
         main_cash_register.save
 
         format.html { redirect_to pointsales_url, success: "El punto de venta " + @pointsale.name + " fue creado." }
@@ -158,12 +153,7 @@ class PointsalesController < ApplicationController
     respond_to do |format|
       @products = JSON.parse params[:products]
       @products.each do |product|
-        available = AvailableProduct.new
-        available.product_id = product['id']
-        available.pointsale_id = params[:pointsale_id]
-        available.stock_min = 0
-        available.stock_max = 0
-        available.stock = product['stock']
+        available = AvailableProduct.new(product_id: product['id'], pointsale_id: params[:pointsale_id], stock_min: 0, stock_max: 0, stock: product['stock'], price_sale: product['price'].to_f > 0 ? product['price'].to_f : Product.find(product['id']).price_sale)
         available.save
       end
       format.json { head :ok }

+ 15 - 13
app/controllers/pos_configs_controller.rb

@@ -3,7 +3,7 @@ class PosConfigsController < ApplicationController
   ##--- Breadcrum_rails
   add_breadcrumb I18n.t("breadcrumbs." + controller_name), :pos_configs_path
 
-  before_action :set_pos_config, only: [:show, :edit, :update, :destroy]
+  before_action :set_pos_config, only: [:update, :destroy]
 
   # GET /pos_configs
   # GET /pos_configs.json
@@ -15,9 +15,10 @@ class PosConfigsController < ApplicationController
   # POST /pos_configs.json
   def create
     @pos_config = PosConfig.new(pos_config_params)
+    @pos_config.skip_haggle_percent = true if params[:pos_config][:enable_haggle] == "false"
     respond_to do |format|
       if @pos_config.save
-        format.html { redirect_to root_path, notice: 'Configuración de parametros generales guardada correctamente.' }
+        format.html { redirect_to root_path, notice: 'Configuración de parámetros generales guardada correctamente.' }
         format.json { render :show, status: :created, location: @pos_config }
       else
         format.html { render action: "index" }
@@ -29,10 +30,11 @@ class PosConfigsController < ApplicationController
   # PATCH/PUT /pos_configs/1
   # PATCH/PUT /pos_configs/1.json
   def update
+    @pos_config.skip_haggle_percent = true if params[:pos_config][:enable_haggle] == "false"
     respond_to do |format|
-      @pos_config.audit_comment = "Se actualizó parametros generales"
+      @pos_config.audit_comment = "Se actualizaron los parámetros generales"
       if @pos_config.update(pos_config_params)
-        format.html { redirect_to root_path, notice: 'Configuración de parametros generales guardada correctamente.' }
+        format.html { redirect_to root_path, notice: 'Configuración de parámetros generales guardada correctamente.' }
         format.json { render :show, status: :ok, location: @pos_config }
       else
         format.html { render action: "index" }
@@ -42,14 +44,14 @@ class PosConfigsController < ApplicationController
   end
 
   private
-    # Use callbacks to share common setup or constraints between actions.
-    def set_pos_config
-      @pos_config = PosConfig.first
-    end
+  # Use callbacks to share common setup or constraints between actions.
+  def set_pos_config
+    @pos_config = PosConfig.first
+  end
 
-    # Never trust parameters from the scary internet, only allow the white list through.
-    def pos_config_params
-      params[:pos_config]
-        params.require(:pos_config).permit(:cancel_partial_payment, :refund_sale, :days_cancel_sale, :days_cancel_purchase, :tax_percent, :time_zone, :gain_margin, :ticket_description, :reserve_sale_percent, :days_cancel_reserved, :commission_percent, :ticket_footer, :ticket_img, :ticket_img_cache, :haggle_in_sale_percent)
-    end
+  # Never trust parameters from the scary internet, only allow the white list through.
+  def pos_config_params
+    params[:pos_config]
+    params.require(:pos_config).permit(:cancel_partial_payment, :refund_sale, :days_cancel_sale, :days_cancel_purchase, :tax_percent, :time_zone, :gain_margin, :ticket_description, :reserve_sale_percent, :days_cancel_reserved, :commission_percent, :ticket_footer, :ticket_img, :ticket_img_cache, :haggle_in_sale_percent, :enable_haggle)
+  end
 end

+ 24 - 35
app/controllers/product_wastes_controller.rb

@@ -13,13 +13,15 @@ class ProductWastesController < ApplicationController
   # GET /product_wastes
   # GET /product_wastes.json
   def index
-    if current_user.usertype == 'A'
-      @product_wastes = ProductWaste.includes(:product, :user, :pointsale, :warehouse).activos
-    elsif current_user.usertype == 'G' || current_user.usertype == 'C'
-      @product_wastes = ProductWaste.includes(:product, :user).where(pointsale_id: current_user.pointsale_id).activos
-    elsif current_user.usertype == 'S'
-      @product_wastes = ProductWaste.includes(:product, :user).where(warehouse_id: current_user.warehouse_id).activos
-    end
+    @product_wastes = ProductWaste.includes(:product, :user, :pointsale, :warehouse).activos
+    @product_wastes =
+      if current_user.usertype == 'G' || current_user.usertype == 'C'
+        @product_wastes.where(pointsale_id: current_user.pointsale_id)
+      elsif current_user.usertype == 'S'
+        @product_wastes.where(warehouse_id: current_user.warehouse_id)
+      else
+        @product_wastes
+      end
   end
 
   # GET /product_wastes/new
@@ -28,20 +30,21 @@ class ProductWastesController < ApplicationController
   # POST /product_wastes
   # POST /product_wastes.json
   def create
-    respond_to do |format|
-      @product_waste = ProductWaste.new(product_waste_params)
-      @product_waste.user_id = current_user.id
-      @product_waste.status = :active
+    @product_waste = ProductWaste.new(product_waste_params)
+    @product_waste.user_id = current_user.id
+    @product_waste.status = :active
 
-      if current_user.usertype == 'S'
-        @product_waste.warehouse_id = current_user.warehouse_id
-        @stock = WarehouseStock.find_by(warehouse_id: @product_waste.warehouse_id, product_id: @product_waste.product_id)
-      else
-        @product_waste.pointsale_id = current_user.pointsale_id
-        @stock = AvailableProduct.find_by(pointsale_id: @product_waste.pointsale_id, product_id: @product_waste.product_id)
-      end
+    if current_user.usertype == 'S'
+      @product_waste.warehouse_id = current_user.warehouse_id
+      @stock = WarehouseStock.find_by(warehouse_id: @product_waste.warehouse_id, product_id: @product_waste.product_id)
+    else
+      @product_waste.pointsale_id = current_user.pointsale_id
+      @stock = AvailableProduct.find_by(pointsale_id: @product_waste.pointsale_id, product_id: @product_waste.product_id)
+    end
+
+    respond_to do |format|
       if @stock.stock >= @product_waste.quantity
-        @product_waste.audit_comment = "Merma del producto #{@product_waste.product.name}  creada"
+        @product_waste.audit_comment = "Merma del producto #{@product_waste.product.name} creada"
         if @product_waste.save
           @stock.stock -= @product_waste.quantity
           @stock.save
@@ -50,31 +53,17 @@ class ProductWastesController < ApplicationController
           format.json { render json: @product_waste.errors.values, status: :unprocessable_entity }
         end
       else
-        @product_waste.errors.add(:base, "Stock insuficiente, solo se cuenta con #{@stock.stock} unidades del producto #{@product_waste.product.name}")
+        @product_waste.errors.add(:base, "Stock insuficiente, sólo se cuenta con #{@stock.stock} unidades del producto #{@product_waste.product.name}")
         format.json { render json: @product_waste.errors.values, status: :unprocessable_entity }
       end
     end
   end
 
-  # PATCH/PUT /product_wastes/1
-  # PATCH/PUT /product_wastes/1.json
-  def update
-    respond_to do |format|
-      if @product_waste.update(product_waste_params)
-        format.html { redirect_to @product_waste, notice: 'Product waste was successfully updated.' }
-        format.json { render :show, status: :ok, location: @product_waste }
-      else
-        format.html { render :edit }
-        format.json { render json: @product_waste.errors, status: :unprocessable_entity }
-      end
-    end
-  end
-
   # DELETE /product_wastes/1
   # DELETE /product_wastes/1.json
   def destroy
     respond_to do |format|
-      @product_waste.audit_comment = "Merma del producto #{@product_waste.product.name}  eliminada."
+      @product_waste.audit_comment = "Merma del producto #{@product_waste.product.name} eliminada."
       if @product_waste.update_attributes(status: :inactive)
         @stock = current_user.usertype == "S" ? WarehouseStock.find_by(warehouse_id: @product_waste.warehouse_id, product_id: @product_waste.product_id) : AvailableProduct.find_by(pointsale_id: @product_waste.pointsale_id, product_id: @product_waste.product_id)
         @stock.stock = @stock.stock + @product_waste.quantity

File diff suppressed because it is too large
+ 5 - 1
app/controllers/products_controller.rb


+ 1 - 1
app/controllers/products_returns_controller.rb

@@ -12,7 +12,7 @@ class ProductsReturnsController < ApplicationController
   # GET /products_returns
   # GET /products_returns.json
   def index
-    @products_returns = current_user.usertype == 'A' ? ProductsReturn.all.includes(:sale, :user, :pointsale) : Pointsale.find(current_user.pointsale_id).products_returns.includes(:sale, :user).order(" products_returns.id DESC ")
+    @products_returns = current_user.usertype == "A" || current_user.usertype == "SS" ? ProductsReturn.all.includes(:sale, :user, :pointsale) : Pointsale.find(current_user.pointsale_id).products_returns.includes(:sale, :user).order(" products_returns.id DESC ")
   end
 
   # GET /products_returns/1

+ 86 - 102
app/controllers/purchases_controller.rb

@@ -1,13 +1,12 @@
 class PurchasesController < ApplicationController
-
   ##--- Abilities
   load_and_authorize_resource
 
   ##--- Breadcrum_rails
   add_breadcrumb I18n.t("breadcrumbs." + controller_name), :purchases_path
   add_breadcrumb "Nueva " + I18n.t("breadcrumbs." + controller_name).singularize, :new_purchase_path, only: :new
-  add_breadcrumb "Detalle de la " + I18n.t("breadcrumbs." + controller_name).singularize , :purchase_path, only: :show
-  add_breadcrumb "Editar " + I18n.t("breadcrumbs." + controller_name).singularize , :edit_purchase_path, only: :edit
+  add_breadcrumb "Detalle de la " + I18n.t("breadcrumbs." + controller_name).singularize, :purchase_path, only: :show
+  add_breadcrumb "Editar " + I18n.t("breadcrumbs." + controller_name).singularize, :edit_purchase_path, only: :edit
 
   before_action :set_purchase, only: [:show, :edit, :update, :destroy]
   before_action :get_filters, only: [:index, :show, :edit, :new]
@@ -15,17 +14,17 @@ class PurchasesController < ApplicationController
   # GET /purchases
   # GET /purchases.json
   def index
-    if current_user.usertype == "A"
-      @purchases = Purchase.all.includes(:supplier, :pointsale, :warehouse, :user).order("created_at DESC")
-    else
-      @purchases = Purchase.includes(:supplier, :user).where(:pointsale_id => current_user.pointsale_id).order('created_at desc')
-    end
+    @purchases =
+      if current_user.usertype == "A" || current_user.usertype == "SS"
+        Purchase.all.includes(:supplier, :pointsale, :warehouse, :user).order("created_at DESC")
+      else
+        Purchase.includes(:supplier, :user).where(pointsale_id: current_user.pointsale_id).order('created_at desc')
+      end
   end
 
   # GET /purchases/1
   # GET /purchases/1.json
-  def show
-  end
+  def show; end
 
   # GET /purchases/new
   def new
@@ -38,18 +37,18 @@ class PurchasesController < ApplicationController
     @destiny = 'warehouse'
     @purchase = Purchase.new
     @purchase.purchase_details.new
-    @pre_purchases = PrePurchase.where(:user_id => current_user.id)
-    if @pre_purchases.size > 0
+    @pre_purchases = PrePurchase.where(user_id: current_user.id)
+    unless @pre_purchases.empty?
       @purchase.supplier_id = @pre_purchases[0].supplier_id
       @purchase.pointsale_id = @pre_purchases[0].pointsale_id
-      @purchase.warehouse_id =  @pre_purchases[0].warehouse_id
+      @purchase.warehouse_id = @pre_purchases[0].warehouse_id
       @destiny = @purchase.pointsale_id.present? ? 'pointsale' : 'warehouse'
       @purchase.exchange = @pre_purchases[0].exchange if @pre_purchases[0].exchange.present?
       @purchase.is_in_dollars = true if @pre_purchases[0].exchange.present?
       @disable_supplier = true
       @disable_pointsale = true
       @disable_warehouse = true
-      @disable_is_in_dollars =  true
+      @disable_is_in_dollars = true
       @disable_destiny = true
       @disabled_button = false
     end
@@ -68,7 +67,7 @@ class PurchasesController < ApplicationController
     @purchase = Purchase.new(purchase_params)
     @purchase.user_id = current_user.id
     @purchase.status = :notpaid
-    @pre_purchases = PrePurchase.where(:user_id => current_user.id)
+    @pre_purchases = PrePurchase.where(user_id: current_user.id)
 
     respond_to do |format|
       message = "compra #{@purchase.purchase_code} por #{@purchase.total} creada."
@@ -76,51 +75,7 @@ class PurchasesController < ApplicationController
       if @purchase.save
         @pre_purchases.each do |pre_purchase|
           # agregar detalles de la compra
-          detail = PurchaseDetail.new
-          detail.product_id = pre_purchase.product_id
-          detail.quantity = pre_purchase.quantity
-          detail.amount = pre_purchase.total
-          detail.price = pre_purchase.price_base
-          detail.tax = pre_purchase.tax
-          @purchase.purchase_details << detail
-          # actualizar stock del producto cuando es para punto de venta
-          if @purchase.pointsale_id.present?
-            stockProduct = AvailableProduct.find_by(:product_id => detail.product_id, :pointsale_id => @purchase.pointsale_id)
-            if stockProduct.present?
-              stockProduct.stock = 0 if stockProduct.stock.blank?
-              stockProduct.stock += detail.quantity
-              stockProduct.save
-            else
-              stockProduct = AvailableProduct.new
-              stockProduct.product_id = detail.product_id
-              stockProduct.pointsale_id = @purchase.pointsale_id
-              stockProduct.stock = detail.quantity
-              stockProduct.save
-            end
-          else
-            # actualizar stock del producto cuando es para punto de venta
-            stockProduct = WarehouseStock.find_by(:product_id => detail.product_id, :warehouse_id => @purchase.warehouse_id)
-            if stockProduct.present?
-              stockProduct.stock = 0 if stockProduct.stock.blank?
-              stockProduct.stock += detail.quantity
-              stockProduct.save
-            else
-              stockProduct = WarehouseStock.new
-              stockProduct.product_id = detail.product_id
-              stockProduct.warehouse_id = @purchase.warehouse_id
-              stockProduct.stock = detail.quantity
-              stockProduct.save
-            end
-          end
-          # guardar en bitacora de inventario
-          move = InventoriesMove.new
-          move.product_id = detail.product_id
-          move.purchase_id = @purchase.id
-          move.quantity = detail.quantity
-          move.move_type = "incoming"
-          move.reason = "purchase"
-          move.save
-
+          create_purchase_details(@purchase, pre_purchase)
           pre_purchase.destroy
         end
         format.html { redirect_to purchases_url, success: message }
@@ -137,34 +92,15 @@ class PurchasesController < ApplicationController
     respond_to do |format|
       message = "Compra #{@purchase.purchase_code} cancelada."
       @purchase.audit_comment = message
-      if @purchase.update_attributes(:status => :cancelled)
-        #checa si hay pagos de esta compra
-        CashRegistersMove.where(:purchase_id => @purchase.id).each do |move|
+      if @purchase.update_attributes(status: :cancelled)
+        # checa si hay pagos de esta compra
+        CashRegistersMove.where(purchase_id: @purchase.id).each do |move|
           new_cash_move = move.dup
           new_cash_move.move_type = :ingreso
           new_cash_move.save
         end
-
         @purchase.purchase_details.each do |detail|
-          detail.update_attributes(:status => :inactive)
-          #busca y actualiza el stock de productos
-          if @purchase.pointsale.present?
-            stockProduct = AvailableProduct.find_by(:product_id => detail.product_id, :pointsale_id => @purchase.pointsale_id)
-          else
-            stockProduct = WarehouseStock.find_by(:product_id => detail.product_id, :warehouse_id => @purchase.warehouse_id)
-          end
-          # restarle al stock del producto
-          stock = stockProduct.stock - detail.quantity
-          stockProduct.update_attributes(:stock => stock)
-
-          # guardar en bitacora de inventario
-          move = InventoriesMove.new
-          move.product_id = detail.product_id
-          move.purchase_id = @purchase.id
-          move.quantity = detail.quantity
-          move.move_type = "outgoing"
-          move.reason = "purchase_cancel"
-          move.save
+          destroy_purchase_details(@purchase, detail)
         end
         format.html { redirect_to purchases_url, warning: message }
         format.json { head :no_content }
@@ -176,35 +112,83 @@ class PurchasesController < ApplicationController
   end
 
   def find_purchases_by_date
-    startDate = DateTime.parse(params[:begin_date])
-    endDate = DateTime.parse(params[:end_date])
-    if current_user.usertype == "A"
-      @purchases = Purchase.includes(:supplier, :pointsale, :warehouse, :user).where(:purchase_date => startDate..endDate).order('purchase_date desc')
-    else
-      @purchases = Purchase.includes(:supplier, :user).where(:pointsale_id => current_user.pointsale_id, :created_at => startDate..endDate).order('purchase_date desc')
-    end
+    start_date = DateTime.parse(params[:begin_date])
+    end_date = DateTime.parse(params[:end_date])
+    @purchases =
+      if current_user.usertype == "A" || current_user.usertype == "SS"
+        Purchase.includes(:supplier, :pointsale, :warehouse, :user).where(purchase_date: start_date..end_date).order('purchase_date desc')
+      else
+        Purchase.includes(:supplier, :user).where(pointsale_id: current_user.pointsale_id, created_at: start_date..end_date).order('purchase_date desc')
+      end
     respond_to do |format|
       format.js
     end
   end
 
   private
-    # Use callbacks to share common setup or constraints between actions.
-    def set_purchase
-      @purchase = Purchase.find(params[:id])
-    end
 
-    def get_filters
+  # Use callbacks to share common setup or constraints between actions.
+  def set_purchase
+    @purchase = Purchase.find(params[:id])
+  end
+
+  def get_filters
+    @current_page =
       if params[:current_page].blank?
-        @current_page = 1
+        1
       else
-        @current_page = params[:current_page]
+        params[:current_page]
       end
-      @filter = params[:filter]
-    end
+    @filter = params[:filter]
+  end
 
-    # Never trust parameters from the scary internet, only allow the white list through.
-    def purchase_params
-      params.require(:purchase).permit(:supplier_id, :pointsale_id, :warehouse_id ,:purchase_code, :amount, :tax, :total, :observations, :purchase_date, :is_in_dollars, :exchange)
+  def create_purchase_details(purchase, pre_purchase)
+    detail = PurchaseDetail.new(product_id: pre_purchase.product_id, quantity: pre_purchase.quantity, amount: pre_purchase.total, price: pre_purchase.price_base, tax: pre_purchase.tax)
+    purchase.purchase_details << detail
+    # actualizar stock del producto cuando es para punto de venta
+    if purchase.pointsale_id.present?
+      stock_product = AvailableProduct.find_by(product_id: detail.product_id, pointsale_id: purchase.pointsale_id)
+      if stock_product.nil?
+        stock_product = AvailableProduct.create(product_id: detail.product_id, pointsale_id: purchase.pointsale_id, stock: detail.quantity)
+      else
+        stock_product = 0 if stock_product.stock.blank?
+        stock_product.stock += detail.quantity
+      end
+    else
+      # actualizar stock del producto cuando es para almacen
+      stock_product = WarehouseStock.find_by(product_id: detail.product_id, warehouse_id: purchase.warehouse_id)
+      if stock_product.nil?
+        stock_product = WarehouseStock.create(product_id: detail.product_id, warehouse_id: purchase.warehouse_id, stock: detail.quantity)
+      else
+        stock_product = 0 if stock_product.stock.blank?
+        stock_product.stock += detail.quantity
+      end
     end
+    stock_product.save
+
+    # guardar en bitacora de inventario
+    InventoriesMove.create(product_id: detail.product_id, purchase_id: purchase.id, quantity: detail.quantity, move_type: "incoming", reason: "purchase")
+  end
+
+  def destroy_purchase_details(purchase, purchase_detail)
+    purchase_detail.update_attributes(status: :inactive)
+    # busca y actualiza el stock de productos
+    stock_product =
+      if purchase.pointsale.present?
+        AvailableProduct.find_by(product_id: purchase_detail.product_id, pointsale_id: purchase.pointsale_id)
+      else
+        WarehouseStock.find_by(product_id: purchase_detail.product_id, warehouse_id: purchase.warehouse_id)
+      end
+    # restarle al stock del producto
+    stock = stock_product.stock - purchase_detail.quantity
+    stock_product.update_attributes(stock: stock)
+
+    # guardar en bitacora de inventario
+    InventoriesMove.create(product_id: purchase_detail.product_id, purchase_id: purchase.id, quantity: purchase_detail.quantity, move_type: "outgoing", reason: "purchase_cancel")
+  end
+
+  # Never trust parameters from the scary internet, only allow the white list through.
+  def purchase_params
+    params.require(:purchase).permit(:supplier_id, :pointsale_id, :warehouse_id, :purchase_code, :amount, :tax, :total, :observations, :purchase_date, :is_in_dollars, :exchange)
+  end
 end

+ 30 - 0
app/controllers/reports_controller.rb

@@ -0,0 +1,30 @@
+class ReportsController < ApplicationController
+  ##--- Breadcrum_rails
+  add_breadcrumb I18n.t("breadcrumbs." + controller_name), :reports_path
+  add_breadcrumb "Reporte de mínimos y máximos", :min_max_path, only: :min_max
+
+  def min_max
+    @pointsales = Pointsale.activos
+    respond_to do |format|
+      if params[:pointsale_id].present?
+        @products = AvailableProduct.joins(:product, :categories).activos.where(pointsale_id: params[:pointsale_id]).where("available_products.stock <= available_products.stock_min and available_products.stock_max > ?", 0)
+        @products = get_products_category(@products, params[:category], params[:subcategory]) if params[:category].present?
+        format.js
+      else
+        @products = AvailableProduct.where(pointsale_id: @pointsales.first.id).where("available_products.stock <= available_products.stock_min and available_products.stock_min > ?", 0)
+        format.html
+      end
+    end
+  end
+
+  def get_products_category(products, category, subcategory)
+    ids =
+      if subcategory.present?
+        subcategory
+      else
+        category = Category.find(category)
+        [category.id, category.children.ids].flatten
+      end
+    products.where(categories: { id: ids })
+  end
+end

+ 39 - 37
app/controllers/sales_controller.rb

@@ -15,13 +15,13 @@ class SalesController < ApplicationController
   def index
     today = Date.current
     thirty_day_ago = today - 30
-    @sales = current_user.usertype == 'A' ? Sale.includes(:customer, :user, :seller, :sales_details).where(date_sale: thirty_day_ago..today).where.not(saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.includes(:customer, :user, :seller).where(date_sale: thirty_day_ago..today).where.not(saletype: 2).order("created_at DESC")
+    @sales = current_user.usertype == "A" || current_user.usertype == "SS" ? Sale.includes(:customer, :user, :seller, :sales_details).where(date_sale: thirty_day_ago..today).where.not(saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.includes(:customer, :user, :seller).where(date_sale: thirty_day_ago..today).where.not(saletype: 2).order("created_at DESC")
   end
 
   def sales_reserved
     beg_of_month = Date.current.beginning_of_month
     end_of_month = Date.current.end_of_month
-    @sales = current_user.usertype == 'A' ? Sale.where(saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.where(saletype: 2).order(" created_at DESC")
+    @sales = current_user.usertype == "A" || current_user.usertype == "SS" ? Sale.where(saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.where(saletype: 2).order(" created_at DESC")
   end
 
   # GET /sales/1
@@ -45,8 +45,10 @@ class SalesController < ApplicationController
     @disabled_select = false
     @disabled_button = true
     @enable_radios = true
-    @opened_cash_registers = Pointsale.find(current_user.pointsale_id).open_cash_registers.abiertas
+    pointsale = Pointsale.find(current_user.pointsale_id)
+    @opened_cash_registers = pointsale.open_cash_registers.abiertas
     @sale.open_cash_register_id = session[:open_cash_register_id] || nil
+    @seller = @sale.seller_id.present? ? @sale.seller_id : pointsale.sales.activas.last.seller_id
     if @pre_sales.present?
       @sale.saletype = @pre_sales[0].sale_type
       @sale.customer_id = @pre_sales[0].customer_id
@@ -193,7 +195,7 @@ class SalesController < ApplicationController
       start_date = Date.today.beginning_of_month
       end_date = Date.today.end_of_month
     end
-    @sales = current_user.usertype == 'A' ? Sale.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date).where.not(saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date).where.not(saletype: 2).order(" created_at DESC ")
+    @sales = current_user.usertype == "A" || current_user.usertype == "SS" ? Sale.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date).where.not(saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date).where.not(saletype: 2).order(" created_at DESC ")
     respond_to do |format|
       format.js
     end
@@ -223,7 +225,7 @@ class SalesController < ApplicationController
       start_date = Date.today.beginning_of_month
       end_date = Date.today.end_of_month
     end
-    @sales = current_user.usertype == 'A' ? Sale.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date, saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date).where(saletype: 2).order(" created_at DESC ")
+    @sales = current_user.usertype == "A" || current_user.usertype == "SS" ? Sale.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date, saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.includes(:customer, :user, :seller, :sales_details).where(date_sale: start_date..end_date).where(saletype: 2).order(" created_at DESC ")
 
     respond_to do |format|
       format.js
@@ -325,7 +327,7 @@ class SalesController < ApplicationController
 
   def add_haggle
     @pre_sale = PreSale.find(params[:pre_sale])
-    @haggle_percent = current_user.pointsale.haggle_percent.zero? ? @pos_config.haggle_in_sale_percent : current_user.pointsale.haggle_percent
+    @haggle_percent = !current_user.pointsale.haggle_percent.blank? ? current_user.pointsale.haggle_percent : @pos_config.haggle_in_sale_percent
     @suggested_haggle = (@haggle_percent.to_f / 100) * @pre_sale.unit_price
   end
 
@@ -366,38 +368,38 @@ class SalesController < ApplicationController
   end
 
   def sales_per_month
-    respond_to do |format|
-      # start_date = DateTime.parse(params[:start_date])
-      # end_date = DateTime.parse(params[:end_date])
-      start_date = DateTime.parse(params[:start_date]).in_time_zone(Time.zone).beginning_of_day + 1.days
-      end_date = DateTime.parse(params[:end_date]).in_time_zone(Time.zone).end_of_day + 1.days
-      @cash_sales_total = 0
-      @reserved_sales_total = 0
-      @credit_sales_total = 0
-
-      if params[:pointsale_id].present?
-        @pointsale = Pointsale.find(params[:pointsale_id])
-        @incomes_in_period = @pointsale.cash_registers_moves.joins(:sale).where(move_type: '1', created_at: start_date..end_date)
-        @sales = @pointsale.sales.activas.where(created_at: start_date..end_date).order("id DESC")
-      else
-        @incomes_in_period = CashRegistersMove.joins(:sale).where(move_type: '1', created_at: start_date..end_date)
-        @sales = Sale.activas.where(created_at: start_date..end_date).order("id DESC")
-      end
+    # start_date = DateTime.parse(params[:start_date])
+    # end_date = DateTime.parse(params[:end_date])
+    start_date = DateTime.parse(params[:start_date]).in_time_zone(Time.zone).beginning_of_day + 1.days
+    end_date = DateTime.parse(params[:end_date]).in_time_zone(Time.zone).end_of_day + 1.days
+    @cash_sales_total = 0
+    @reserved_sales_total = 0
+    @credit_sales_total = 0
+
+    if params[:pointsale_id].present?
+      @pointsale = Pointsale.find(params[:pointsale_id])
+      @incomes_in_period = @pointsale.cash_registers_moves.joins(:sale).where(move_type: '1', created_at: start_date..end_date)
+      @sales = @pointsale.sales.includes(:sales_details, :user, :seller).activas.where(created_at: start_date..end_date).order("id DESC")
+    else
+      @incomes_in_period = CashRegistersMove.joins(:sale).where(move_type: '1', created_at: start_date..end_date)
+      @sales = Sale.includes(:sales_details, :user, :seller).activas.where(created_at: start_date..end_date).order("id DESC")
+    end
 
-      @sales_quantity = @sales.size
-      @prods_total = SalesDetail.where("sale_id IN (?)", @sales.pluck(:id)).sum(:quantity).round
-      # @cash_sales_income = CashRegistersMove.activos.where("sale_id IN (?)", @sales.where(saletype: 1).pluck(:id)).where(created_at: start_date..end_date).sum(:quantity)
-      # @reserved_sales_income = CashRegistersMove.activos.where("sale_id IN (?)", @sales.where(saletype: 2).pluck(:id)).where(created_at: start_date..end_date).sum(:quantity)
-      # @credit_sales_income = CashRegistersMove.activos.where("sale_id IN (?)", @sales.where(saletype: 0).pluck(:id)).where(created_at: start_date..end_date).sum(:quantity)
-      @cash_sales_income = @incomes_in_period.where('sales.saletype = 1').sum(:quantity)
-      @reserved_sales_income = @incomes_in_period.where('sales.saletype = 2').sum(:quantity)
-      @credit_sales_income = @incomes_in_period.where('sales.saletype = 0').sum(:quantity)
-      @sales_income = @incomes_in_period.sum(:quantity)
-
-      @cash_sales_total = @sales.where(saletype: 1).sum(:total)
-      @reserved_sales_total = @sales.where(saletype: 2).sum(:total)
-      @credit_sales_total = @sales.where(saletype: 0).sum(:total)
-      @sales_total = @sales.sum(:total)
+    @sales_quantity = @sales.size
+    @prods_total = SalesDetail.where("sale_id IN (?)", @sales.pluck(:id)).sum(:quantity).round
+    # @cash_sales_income = CashRegistersMove.activos.where("sale_id IN (?)", @sales.where(saletype: 1).pluck(:id)).where(created_at: start_date..end_date).sum(:quantity)
+    # @reserved_sales_income = CashRegistersMove.activos.where("sale_id IN (?)", @sales.where(saletype: 2).pluck(:id)).where(created_at: start_date..end_date).sum(:quantity)
+    # @credit_sales_income = CashRegistersMove.activos.where("sale_id IN (?)", @sales.where(saletype: 0).pluck(:id)).where(created_at: start_date..end_date).sum(:quantity)
+    @cash_sales_income = @incomes_in_period.where('sales.saletype = ?', 1).sum(:quantity)
+    @reserved_sales_income = @incomes_in_period.where('sales.saletype = ?', 2).sum(:quantity)
+    @credit_sales_income = @incomes_in_period.where('sales.saletype = ?', 0).sum(:quantity)
+    @sales_income = @incomes_in_period.sum(:quantity)
+
+    @cash_sales_total = @sales.where(saletype: 1).sum(:total)
+    @reserved_sales_total = @sales.where(saletype: 2).sum(:total)
+    @credit_sales_total = @sales.where(saletype: 0).sum(:total)
+    @sales_total = @sales.sum(:total)
+    respond_to do |format|
       format.js
     end
   end

+ 39 - 41
app/controllers/sellers_controller.rb

@@ -8,25 +8,24 @@ class SellersController < ApplicationController
 
   ##--- Breadcrum_rails
   add_breadcrumb I18n.t("breadcrumbs." + controller_name), :sellers_path
-  add_breadcrumb "Nuevo vendedor " , :new_seller_path, only: :new
-  add_breadcrumb "Detalle del vendedor "  , :seller_path, only: :show
-  add_breadcrumb "Editar vendedor "  , :edit_seller_path, only: :edit
+  add_breadcrumb "Nuevo vendedor ", :new_seller_path, only: :new
+  add_breadcrumb "Detalle del vendedor ", :seller_path, only: :show
+  add_breadcrumb "Editar vendedor ", :edit_seller_path, only: :edit
 
   # GET /sellers
   # GET /sellers.json
   def index
-    @sellers = (current_user.usertype == "A" ? Seller.vigentes.includes(:pointsale) : Seller.where(:pointsale_id => current_user.pointsale_id).vigentes)
+    @sellers = current_user.usertype == "A" || current_user.usertype == "SS" ? Seller.vigentes.includes(:pointsale) : Seller.where(pointsale_id: current_user.pointsale_id).vigentes
   end
 
   # GET /sellers/1
   # GET /sellers/1.json
-  def show
-  end
+  def show; end
 
   # GET /sellers/new
   def new
     @seller = Seller.new
-    if current_user.usertype != "A"
+    if current_user.usertype != "A" || current_user.usertype != "SS"
       @pointsale_id = current_user.pointsale_id
     end
   end
@@ -40,7 +39,7 @@ class SellersController < ApplicationController
   # POST /sellers.json
   def create
     @seller = Seller.new(seller_params)
-    if current_user.usertype != "A"
+    unless current_user.usertype == "A" || current_user.usertype == "SS"
       @seller.skip_pointsale = true
       @seller.pointsale_id = current_user.pointsale_id
     end
@@ -48,10 +47,10 @@ class SellersController < ApplicationController
       message = "El vendedor " + @seller.full_name + " fue registrado."
       @seller.audit_comment = message
       if @seller.save
-        format.html { redirect_to sellers_path, success: message }
-        format.json { render :show, status: :created, location: @seller }
+        format.js
       else
         format.html { render :new }
+        format.js
         format.json { render json: @seller.errors, status: :unprocessable_entity }
       end
     end
@@ -64,10 +63,10 @@ class SellersController < ApplicationController
       message = "El vendedor " + @seller.full_name + " fue modificado."
       @seller.audit_comment = message
       if @seller.update(seller_params)
-        format.html { redirect_to sellers_path, success: message }
-        format.json { render :show, status: :ok, location: @seller }
+        format.js
       else
         format.html { render :edit }
+        format.js
         format.json { render json: @seller.errors, status: :unprocessable_entity }
       end
     end
@@ -75,15 +74,16 @@ class SellersController < ApplicationController
 
   def update_status
     seller = Seller.find(params[:seller_id])
-    if seller.active?
-      seller.status = 2
-    elsif seller.inactive?
-      seller.status = 1
-    end
+    seller.status =
+      if seller.active?
+        2
+      elsif seller.inactive?
+        1
+      end
     respond_to do |format|
-      message = "El vendedor " + seller.full_name + " " + seller.last_name + " fue "+ (seller.active? ? "activado" : "desactivado")+"."
+      message = "El vendedor " + seller.full_name + " fue " + (seller.active? ? "activado" : "desactivado") + "."
       seller.audit_comment = message
-      if seller.save(:validate => false)
+      if seller.save(validate: false)
         format.html { redirect_to sellers_url, warning: message }
         format.json { head :no_content }
       else
@@ -99,7 +99,7 @@ class SellersController < ApplicationController
     respond_to do |format|
       message = "El vendedor " + @seller.full_name + " fue eliminado."
       @seller.audit_comment = message
-      if @seller.update_attributes(:status => 0)
+      if @seller.update_attributes(status: 0)
         format.html { redirect_to sellers_path, warning: message }
         format.json { head :no_content }
       else
@@ -109,30 +109,28 @@ class SellersController < ApplicationController
     end
   end
 
-
-
   private
-    # Use callbacks to share common setup or constraints between actions.
-    def set_seller
-      @seller = Seller.find(params[:id])
-    end
+  # Use callbacks to share common setup or constraints between actions.
+  def set_seller
+    @seller = Seller.find(params[:id])
+  end
 
-    # Never trust parameters from the scary internet, only allow the white list through.
-    def seller_params
-      params.require(:seller).permit(:pointsale_id, :name, :last_name)
-    end
+  # Never trust parameters from the scary internet, only allow the white list through.
+  def seller_params
+    params.require(:seller).permit(:pointsale_id, :name, :last_name)
+  end
 
-    def get_filters
-      if params[:current_page].blank?
-        @current_page = 1
-      else
-        @current_page = params[:current_page]
-      end
-      @filter = params[:filter]
+  def get_filters
+    if params[:current_page].blank?
+      @current_page = 1
+    else
+      @current_page = params[:current_page]
     end
+    @filter = params[:filter]
+  end
 
-    def get_info
-      @users = (current_user.usertype == "A" ? User.active : User.active.where(:pointsale_id => current_user.pointsale_id))
-      @pointsales = Pointsale.activos
-    end
+  def get_info
+    @users = (current_user.usertype == "A" || current_user.usertype == "SS" ? User.active : User.active.where(pointsale_id: current_user.pointsale_id))
+    @pointsales = Pointsale.activos
+  end
 end

+ 1 - 1
app/controllers/special_prices_controller.rb

@@ -5,7 +5,7 @@ class SpecialPricesController < ApplicationController
   ##--- Breadcrum_rails
   add_breadcrumb "Nuevo precio(s) especial", :new_special_price_path, only: :new
 
-  before_action :set_special_price, only: [:show, :edit, :update, :destroy]
+  before_action :set_special_price, only: [:update, :destroy]
 
   # GET /special_prices/new
   def new

+ 28 - 0
app/controllers/supports_controller.rb

@@ -0,0 +1,28 @@
+class SupportsController < ApplicationController
+  ##--- Breadcrum_rails
+  add_breadcrumb I18n.t("breadcrumbs." + controller_name), :supports_path
+  add_breadcrumb "Soporte Técnico", :contact_support_path, only: :contact_support
+
+  def contact_support
+    if params[:support].present?
+      returns = false
+      params[:support].map { |_x, y| returns = true if y.blank? }
+      respond_to do |format|
+        if returns
+          format.js { render "contact_support", locals: { notice: "Debe llenar todos los campos del formulario." } }
+        else
+          SupportMailer.contact_support(params[:support], current_user).deliver_now
+          format.js
+        end
+      end
+    end
+  end
+
+  def system_updates # change the following
+    @date = "2018/08/02" # yyyy/mm/dd
+    @change_points = {
+      "key1" => "Change point 1",
+      "key2" => "Change point 2"
+    }
+  end
+end

+ 1 - 1
app/controllers/transfers_controller.rb

@@ -16,7 +16,7 @@ class TransfersController < ApplicationController
   # GET /transfers.json
   def index
     @transfers = Transfer.includes(:user, :received_by, :transfer_details).all.order('id DESC, transfer_date DESC')
-    unless current_user.usertype == "A"
+    unless current_user.usertype == "A" || current_user.usertype == "SS"
       is_destiny =
         if current_user.usertype == "S"
           id_filter = current_user.warehouse_id

+ 30 - 8
app/controllers/users_controller.rb

@@ -9,14 +9,21 @@ class UsersController < ApplicationController
   before_action :get_filters, only: [:index, :show, :edit, :new]
 
   def index
-    @users = current_user.usertype == 'A' ? User.includes(:pointsale, :warehouse).where('status > 0').order("id desc") : User.includes(:pointsale, :warehouse).where('status > 0 and pointsale_id = ?', current_user.pointsale_id).order("id desc")
+    @users = User.includes(:pointsale, :warehouse).vigentes
+    if current_user.usertype != "SS"
+      @users = @users.where.not(usertype: "SS")
+      @users = @users.where(pointsale_id: current_user.pointsale_id) if current_user.usertype != "A"
+    end
   end
 
   def new
     @user = User.new
+    set_usertypes
   end
 
-  def edit; end
+  def edit
+    set_usertypes
+  end
 
   def update
     respond_to do |format|
@@ -27,6 +34,7 @@ class UsersController < ApplicationController
         format.html { redirect_to users_path, success: message }
         format.json { render :show, status: :ok, location: @user }
       else
+        set_usertypes
         format.html { render :edit }
         format.json { render json: @user.errors, status: :unprocessable_entity }
       end
@@ -36,17 +44,20 @@ class UsersController < ApplicationController
   def create
     @user = User.new(user_params)
     respond_to do |format|
-      message =
-        if @user.usertype == 'A'
-          "usuario #{@user.userid} con perfil ADMINISTRADOR creado."
-        else
-          "Usuario #{@user.userid} creado y asignado al " + (@user.pointsale.present? ? "punto de venta #{@user.pointsale.name}" : "almacén #{@user.warehouse.name}")
-        end
+      message = "Usuario #{@user.userid}"
+      if @user.usertype == 'SS'
+        message += " con perfil SUPER ADMINISTRADOR creado."
+      elsif @user.usertype == "A"
+        message += " con perfil ADMINISTRADOR creado."
+      else
+        message += " creado y asignado al " + (@user.pointsale.present? ? "punto de venta #{@user.pointsale.name}" : "almacén #{@user.warehouse.name}")
+      end
       @user.audit_comment = message
       if @user.save
         format.html { redirect_to users_path, success: message }
         format.json { render :show, status: :created, location: @user }
       else
+        set_usertypes
         format.html { render :new }
         format.json { render json: @user.errors, status: :unprocessable_entity }
       end
@@ -95,6 +106,17 @@ class UsersController < ApplicationController
     end
   end
 
+  def set_usertypes
+    @options_for_select =
+      if current_user.usertype == "SS"
+        Rails.application.config.usertypes_for_super
+      elsif current_user.usertype == "A"
+        Rails.application.config.usertypes_for_admin
+      else
+        Rails.application.config.usertypes_for_manager
+      end
+  end
+
   private
 
   # Use callbacks to share common setup or constraints between actions.

+ 30 - 30
app/controllers/warehouses_controller.rb

@@ -4,8 +4,8 @@ class WarehousesController < ApplicationController
 
   ##--- Breadcrum_rails
   add_breadcrumb I18n.t("breadcrumbs." + controller_name), :warehouses_path
-  add_breadcrumb "Nuevo Almacén " , :new_warehouse_path, only: :new
-  add_breadcrumb "Editar Almacén"  , :edit_warehouse_path, only: :edit
+  add_breadcrumb "Nuevo Almacén ", :new_warehouse_path, only: :new
+  add_breadcrumb "Editar Almacén", :edit_warehouse_path, only: :edit
 
   before_action :set_warehouse, only: [:show, :edit, :update, :destroy]
   before_action :get_filters, only: [:index, :show, :edit, :new]
@@ -18,8 +18,7 @@ class WarehousesController < ApplicationController
 
   # GET /warehouses/1
   # GET /warehouses/1.json
-  def show
-  end
+  def show; end
 
   # GET /warehouses/new
   def new
@@ -27,8 +26,7 @@ class WarehousesController < ApplicationController
   end
 
   # GET /warehouses/1/edit
-  def edit
-  end
+  def edit; end
 
   # POST /warehouses
   # POST /warehouses.json
@@ -39,10 +37,10 @@ class WarehousesController < ApplicationController
       message = "Almacén #{@warehouse.name} creado."
       @warehouse.audit_comment = message
       if @warehouse.save
-        format.html { redirect_to warehouses_path, success: message }
-        format.json { render :show, status: :created, location: @warehouse }
+        format.js
       else
         format.html { render :new }
+        format.js
         format.json { render json: @warehouse.errors, status: :unprocessable_entity }
       end
     end
@@ -55,10 +53,10 @@ class WarehousesController < ApplicationController
       message = "Almacén #{@warehouse.name} modificado."
       @warehouse.audit_comment = message
       if @warehouse.update(warehouse_params)
-        format.html { redirect_to warehouses_path, success: message }
-        format.json { render :show, status: :ok, location: @warehouse }
+        format.js
       else
         format.html { render :edit }
+        format.js
         format.json { render json: @warehouse.errors, status: :unprocessable_entity }
       end
     end
@@ -78,15 +76,16 @@ class WarehousesController < ApplicationController
 
   def update_status
     warehouse = Warehouse.find(params[:warehouse_id])
-    if warehouse.active?
-      warehouse.status = "inactive"
-    elsif warehouse.inactive?
-      warehouse.status = "active"
-    end
+    warehouse.status =
+      if warehouse.active?
+        "inactive"
+      elsif warehouse.inactive?
+        "active"
+      end
     respond_to do |format|
-      message = "El almacen " + warehouse.name + " fue "+ (warehouse.active? ? "activado" : "desactivado")+"."
+      message = "El almacen " + warehouse.name + " fue " + (warehouse.active? ? "activado" : "desactivado") + "."
       warehouse.audit_comment = message
-      if warehouse.save(:validate => false)
+      if warehouse.save(validate: false)
         format.html { redirect_to warehouses_path, warning: message }
         format.json { head :no_content }
       else
@@ -97,22 +96,23 @@ class WarehousesController < ApplicationController
   end
 
   private
-    # Use callbacks to share common setup or constraints between actions.
-    def set_warehouse
-      @warehouse = Warehouse.find(params[:id])
-    end
+  # Use callbacks to share common setup or constraints between actions.
+  def set_warehouse
+    @warehouse = Warehouse.find(params[:id])
+  end
 
-    def get_filters
+  def get_filters
+    @current_page =
       if params[:current_page].blank?
-        @current_page = 1
+        1
       else
-        @current_page = params[:current_page]
+        params[:current_page]
       end
-      @filter = params[:filter]
-    end
+    @filter = params[:filter]
+  end
 
-    # Never trust parameters from the scary internet, only allow the white list through.
-    def warehouse_params
-      params.require(:warehouse).permit(:name, :status, :prefix)
-    end
+  # Never trust parameters from the scary internet, only allow the white list through.
+  def warehouse_params
+    params.require(:warehouse).permit(:name, :status, :prefix)
+  end
 end

+ 21 - 27
app/datatables/available_products_datatable.rb

@@ -1,5 +1,5 @@
 class AvailableProductsDatatable
-  delegate :params, :fa_icon, :available_products_path, to: :@view
+  delegate :params, :fa_icon, :available_products_path, :number_to_currency, to: :@view
 
   def initialize(view, pointsale)
     @view = view
@@ -9,7 +9,7 @@ class AvailableProductsDatatable
   def as_json(*)
     {
       sEcho: params[:sEcho].to_i,
-      iTotalRecords: @pointsale.products.activos_children.size,
+      iTotalRecords: params[:table] == 'in_pointsale' ? @pointsale.products.activos_children.size : products.total_entries,
       iTotalDisplayRecords: products.total_entries,
       aaData: data
     }
@@ -31,7 +31,6 @@ class AvailableProductsDatatable
           '5' => available.stock
         }.compact.reject { |_k, v| v.nil? }
       end
-
     else
       products.map do |product|
         category = product.categories[0]
@@ -41,7 +40,8 @@ class AvailableProductsDatatable
           '1' => product.sku,
           '2' => get_display_name(product),
           '3' => (category.parent_id.zero? ? category.category : category.parent.category),
-          '4' => (category.parent_id != 0 ? category.category : ' ')
+          '4' => (category.parent_id != 0 ? category.category : ' '),
+          '5' => number_to_currency(product.price_sale, precision: 2)
         }.compact.reject { |_k, v| v.nil? }
       end
     end
@@ -49,18 +49,9 @@ class AvailableProductsDatatable
 
   def get_display_name(product)
     name = "<label style='margin-bottom:0px'><strong>#{product.name}</strong></label> <br>"
-
-    if product.display_attributes.present?
-      name += "#{product.display_attributes} <br>"
-    end
-
-    if product.barcode.present?
-      name += "<i class='fa fa-barcode'></i>: #{product.barcode} <br>"
-    end
-
-    if product.description.present?
-      name += "Descripción: #{product.description}"
-    end
+    name += "#{product.display_attributes} <br>" if product.display_attributes.present?
+    name += "<i class='fa fa-barcode'></i>: #{product.barcode} <br>" if product.barcode.present?
+    name += "Descripción: #{product.description}" if product.barcode.present?
     name
   end
 
@@ -69,20 +60,22 @@ class AvailableProductsDatatable
   end
 
   def fetch_products
-    if params[:table] == 'in_pointsale'
-      products = AvailableProduct.activos.where(pointsale_id: params[:id]).activos
-    else
-      products_in_pointsale = @pointsale.products.activos_children.pluck(:id)
-      products = Product.activos_children.where.not(id: products_in_pointsale).order('products.name')
-    end
+    products =
+      if params[:table] == 'in_pointsale'
+        AvailableProduct.joins(:product, :categories).activos.where(pointsale_id: params[:id]).activos
+      else
+        products_in_pointsale = @pointsale.products.activos_children.pluck(:id)
+        Product.joins(:categories).activos_children.where.not(id: products_in_pointsale).order('products.name')
+      end
 
     products = products.page(page).per_page(per_page)
     search = params[:busqueda]
-    name_searched = if search.include? ':'
-                      search[0, search.index(':') - 1]
-                    else
-                      search
-                    end
+    name_searched =
+      if search.include? ':'
+        search[0, search.index(':') - 1]
+      else
+        search
+      end
     unless search.blank?
       products = products.where("products.sku ilike :search or products.name ilike :search", search: "%#{name_searched}%").order('products.name')
       if search.include? ':'
@@ -90,6 +83,7 @@ class AvailableProductsDatatable
         products = products.where('attributes_json ilike :attribute', attribute: "%#{attribute}%")
       end
     end
+
     products
   end
 

+ 58 - 37
app/datatables/products_datatable.rb

@@ -21,40 +21,61 @@ private
 
   def data
     products.map.with_index do |product, index|
-      if product.img_product?
-        img = product.img_product.url(:medium)
-      else
-        img = "/images/small/missing.png"
-      end
-      is_product_available = product.available_in_pointsale?(@current_user.pointsale_id)
-      product_available = product.get_available_in_pointsale(@current_user.pointsale_id) if is_product_available
-      [
-        (index +1),
-        (image_tag img),
-        "<label>#{product.name} </label> <br>  SKU: <b> #{product.sku} </b>
-          #{ '<i class="fa fa-cubes font-yellow-gold"></i>' if product.is_parent }
-          <br>" + (product.parent_id.nil? ? "" : "<small>#{product.display_attributes}</small><br>") + "<i class='fa fa-barcode'></i>: <b> #{product.barcode} </b>  <br>
-          <p> #{product.description} </p>",
-        (@current_user.usertype == 'A' ? (product.is_in_dollars? ? "#{number_to_currency(product.price_base_dollars, precision: 2)} USD" : "#{number_to_currency(product.price_base, precision: 2)} MXN") : nil),
-        "<h3> #{number_to_currency(product.get_price_sale(@current_user.pointsale_id), precision: 2)}</h3>
-          #{ is_product_available && (product_available && !product_available.price_sale.nil?) && @current_user.usertype == 'G' ? ('Precio de venta base <br>' + number_to_currency(product.price_sale, precision: 2) ) : ''}",
-        product.categories[0].category,
-        product.active? ? "<i class='fa fa-check fa-2 font-green'></i>" : "<i class='fa fa-times fa-2 font-red'></i>",
-        get_actions(@current_user.usertype, product, is_product_available, product_available)
-      ].compact
+      img = product.img_product? ? product.img_product.url(:medium) : img = "/images/small/missing.png"
+      product_available = @current_user.usertype == "A" || @current_user.usertype == "SS" ? nil : product.get_available_in_pointsale(@current_user.pointsale_id)
+      arr = [
+              (index + 1),
+              (image_tag img),
+              display_name(product)
+            ]
+      arr << dollar_price(product) if @current_user.usertype == "A" || @current_user.usertype == "SS"
+      arr << [
+                product_price(product, product_available),
+                product.categories[0].category,
+                product.active? ? "<i class='fa fa-check fa-2 font-green'></i>" : "<i class='fa fa-times fa-2 font-red'></i>",
+                get_actions(product, product_available)
+              ]
+      arr.flatten
+    end
+  end
+
+  def display_name(product)
+    display_product = "<label>#{product.name} </label> <br>  SKU: <b> #{product.sku} </b>"
+    display_product += "<i class='fa fa-cubes font-yellow-gold'></i>" if product.is_parent
+    display_product += "<br>" + (product.parent_id.nil? ? "" : "<small>#{product.display_attributes}</small><br>") + "<i class='fa fa-barcode'></i>: <b> #{product.barcode} </b> <br>"
+    display_product += "<p> #{product.description} </p>"
+    display_product
+  end
+
+  def dollar_price(product)
+    if @current_user.usertype == "A" || @current_user.usertype == "SS"
+      product.is_in_dollars? ? "#{number_to_currency(product.price_base_dollars, precision: 2)} USD" : "#{number_to_currency(product.price_base, precision: 2)} MXN"
+    else
+      '.'
     end
   end
 
+  def product_price(product, product_available)
+    if @current_user.usertype == "G"
+      price_sale = product_available.present? && product_available.price_sale.present? ? product_available.price_sale : product.price_sale
+      price = "<h3> #{number_to_currency(price_sale, precision: 2)}</h3>"
+      price += 'Precio de venta base <br>' + number_to_currency(product.price_sale, precision: 2)
+    else
+      ''
+    end
+  end
 
   def products
     @products ||= fetch_products
   end
 
   def fetch_products
-    products = Product.vigentes_parents.includes(:categories)
-    if @current_user.usertype == 'G'
-      products = Product.activos_children
-    end
+    products =
+      if @current_user.usertype == 'G'
+        Product.activos_children
+      else
+        Product.vigentes_parents.includes(:categories)
+      end
     products = products.page(page).per_page(per_page)
     unless params[:busqueda].blank?
       products = products.where("sku ilike :search or name ilike :search", search: "%#{params[:busqueda]}%")
@@ -63,7 +84,7 @@ private
   end
 
   def page
-    params[:start].to_i/per_page + 1
+    params[:start].to_i / per_page + 1
   end
 
   def per_page
@@ -79,19 +100,19 @@ private
     params[:sSortDir_0] == "desc" ? "desc" : "asc"
   end
 
-  def get_actions(usertype, product, is_product_available, product_available)
+  def get_actions(product, product_available)
     links = '<div class="clearfix">'
-    links += link_to(fa_icon('search'), product, {class: 'btn btn-icon-only default filtros', :title=>"Ver producto"})
+    links += link_to(fa_icon('search'), product, { class: 'btn btn-icon-only default filtros', title: "Ver producto" })
 
-    if usertype == 'G'
-      links += (link_to(fa_icon('dollar'), available_product_edit_price_path(product_available), { :remote => true, class: 'btn btn-icon-only green-dark', :title=>"Cambiar precio"})) if is_product_available
-    elsif usertype == 'A'
-      links += link_to(fa_icon('edit'), edit_product_path(product), {class: 'btn btn-icon-only btn-primary filtros', :title=>"Modificar producto"})
-      links += link_to(fa_icon('copy'), product_edit_variants_path(product.id), {:class => 'btn btn-icon-only btn-info filtros', :title=>"Modificar variantes del producto"}) if product.presentation
-      links += link_to(fa_icon('list-alt'), product_prices_path(product),  {:remote => true, :class => 'btn btn-icon-only green-dark', :title=>"Precios en punto de venta"})
-      links += (link_to(fa_icon('toggle-off'), product_update_status_path(product),  :class => 'btn btn-icon-only default', :title=>"Desactivar producto", data: { confirm: '¿Esta seguro de desactivar el producto?', method: 'post'})) if product.active?
-      links += (link_to(fa_icon('toggle-on'), product_update_status_path(product),  :class => 'btn btn-icon-only green-jungle', :title=>"Activar producto", data: { confirm: '¿Esta seguro de activar el producto?', method: 'post'})) if product.inactive?
-      links += (link_to(fa_icon('trash-o'), product, :class => 'btn btn-icon-only btn-danger', :title=>"Eliminar producto", data: { confirm: '¿Esta seguro de eliminar el producto?', method: :delete})) if product.can_be_deleted?
+    if @current_user.usertype == 'G'
+      links += (link_to(fa_icon('dollar'), available_product_edit_price_path(product_available), { remote: true, class: 'btn btn-icon-only green-dark', title: "Cambiar precio" })) if product_available
+    elsif @current_user.usertype == "A" || @current_user.usertype == "SS"
+      links += link_to(fa_icon('edit'), edit_product_path(product), { class: 'btn btn-icon-only btn-primary filtros', title: "Modificar producto" })
+      links += link_to(fa_icon('copy'), product_edit_variants_path(product.id), { class: 'btn btn-icon-only btn-info filtros', title: "Modificar variantes del producto" }) if product.presentation
+      links += link_to(fa_icon('list-alt'), product_prices_path(product), { remote: true, class: 'btn btn-icon-only green-dark', title: "Precios en punto de venta" })
+      links += (link_to(fa_icon('toggle-off'), product_update_status_path(product), class: 'btn btn-icon-only default', title: "Desactivar producto", data: { confirm: '¿Está seguro de desactivar el producto?', method: 'post' })) if product.active?
+      links += (link_to(fa_icon('toggle-on'), product_update_status_path(product), class: 'btn btn-icon-only green-jungle', title: "Activar producto", data: { confirm: '¿Está seguro de activar el producto?', method: 'post' })) if product.inactive?
+      links += (link_to(fa_icon('trash-o'), product, class: 'btn btn-icon-only btn-danger', title: "Eliminar producto", data: { confirm: '¿Esta seguro de eliminar el producto?', method: :delete })) if product.can_be_deleted?
     end
     links += '</div>'
     return links

+ 1 - 1
app/datatables/stock_by_pointsale_datatable.rb

@@ -43,7 +43,7 @@ class StockByPointsaleDatatable
           available.stock_max.round,
           available.stock.round
         ]
-        arr += get_price_sale(available.product) unless @current_user.usertype == "S"
+        arr << get_price_sale(available.product) unless @current_user.usertype == "S"
         arr.compact
       end
     end

+ 22 - 35
app/datatables/stocks_datatable.rb

@@ -1,8 +1,5 @@
 class StocksDatatable
-
-  delegate :params, :image_tag,
-    :available_products_path, :products_initial_stock_path,
-    to: :@view
+  delegate :params, :image_tag, :available_products_path, :products_initial_stock_path, to: :@view
 
   def initialize(view, user, showcolumns)
     @view = view
@@ -10,13 +7,13 @@ class StocksDatatable
     @showcolumns = showcolumns
   end
 
-  def as_json(options = {})
-
-    if @current_user.usertype == 'S'
-      total = WarehouseStock.activos.where(:warehouse_id => @current_user.pointsale_id)
-    else
-      total = AvailableProduct.activos.where(:pointsale_id => @current_user.warehouse_id)
-    end
+  def as_json(_options = {})
+    total =
+      if @current_user.usertype == 'S'
+        WarehouseStock.activos.where(warehouse_id: @current_user.warehouse_id)
+      else
+        AvailableProduct.activos.where(pointsale_id: @current_user.pointsale_id.present? ? @current_user.pointsale_id : params[:pointsale])
+      end
 
     {
       sEcho: params[:sEcho].to_i,
@@ -26,53 +23,44 @@ class StocksDatatable
     }
   end
 
-private
+  private
 
   def data
-    stock.map do | available |
-      if available.product.img_product?
-        img = available.product.img_product.url(:small)
-      else
-        img = "/images/small/missing.png"
-      end
+    stock.map do |available|
+      img = available.product.img_product? ? available.product.img_product.url(:small) : "/images/small/missing.png"
       category = available.product.categories[0]
       {
         'DT_RowId' => "availableProduct_#{available.id}",
         '0' => '<input class="form-control checkboxes" type="checkbox"/>',
         '1' => (image_tag img),
         '2' => available.product.sku,
-        '3' => "#{available.product.name + '<br>' + available.product.display_attributes}",
-        '4' => (category.parent_id == 0 ? category.category : category.parent.category),
+        '3' => available.product.name + '<br>' + available.product.display_attributes,
+        '4' => (category.parent_id.zero? ? category.category : category.parent.category),
         '5' => (category.parent_id != 0 ? category.category : ' '),
         '6' => (@showcolumns == "minMax" ? available.stock_min : available.stock),
         '7' => (@showcolumns == "minMax" ? available.stock_max : nil)
-      }.compact.reject { |k, v| v.nil? }
+      }.compact.reject { |_k, v| v.nil? }
     end
   end
 
-
   def stock
     @stock ||= fetch_stock
   end
 
   def fetch_stock
-    if @current_user.usertype == 'S'
-      stock = WarehouseStock.activos.includes(:product, :categories).where(:warehouse_id => @current_user.warehouse_id).order('products.name')
-    else
-      stock = AvailableProduct.activos.includes(:product, :categories).where(:pointsale_id => @current_user.pointsale_id).order('products.name')
-    end
-
+    stock =
+      if @current_user.usertype == 'S'
+        WarehouseStock.activos.includes(:product, :categories).where(warehouse_id: @current_user.warehouse_id).order('products.name')
+      else
+        AvailableProduct.activos.includes(:product, :categories).where(pointsale_id: @current_user.pointsale_id.present? ? @current_user.pointsale_id : params[:pointsale]).order('products.name')
+      end
     stock = stock.page(page).per_page(per_page)
-
-    unless params[:busqueda].blank?
-      stock = stock.where("products.sku ilike :search or products.name ilike :search", search: "%#{params[:busqueda]}%").order('products.name')
-    end
-
+    stock = stock.where("products.sku ilike :search or products.name ilike :search", search: "%#{params[:busqueda]}%").order('products.name') unless params[:busqueda].blank?
     stock
   end
 
   def page
-    params[:start].to_i/per_page + 1
+    params[:start].to_i / per_page + 1
   end
 
   def per_page
@@ -87,5 +75,4 @@ private
   def sort_direction
     params[:sSortDir_0] == "desc" ? "desc" : "asc"
   end
-
 end

+ 2 - 0
app/helpers/errors_helper.rb

@@ -0,0 +1,2 @@
+module ErrorsHelper
+end

+ 17 - 0
app/helpers/pointsales_helper.rb

@@ -3,4 +3,21 @@ module PointsalesHelper
 		(pointsale.users.blank? ? pointsale.users.new : pointsale.users)
 		pointsale
 	end
+
+  def pointsale_status(pointsale)
+    case pointsale.status
+    when "active" then
+      content_tag(:i, "", class: "fa fa-check font-green")
+    when "inactive" then
+      content_tag(:i, "", class: "fa fa-times font-red")
+    end
+  end
+
+  def product_count(count)
+    if count > 0
+      content_tag(:i, "", class: "fa fa-check font-green")
+    else
+      content_tag(:i, "", class: "fa fa-times font-red")
+    end
+  end
 end

+ 12 - 0
app/helpers/purchases_helper.rb

@@ -1,2 +1,14 @@
 module PurchasesHelper
+  def purchase_status(purchase)
+    case purchase.status
+    when "paid"
+      content_tag(:span, "Pagada", class: "label label-sm label-success")
+    when "cancelled"
+      content_tag(:span, "Cancelada", class: "label label-sm label-danger")
+    when "parcial"
+      content_tag(:span, "Abonada", class: "label label-sm label-warning")
+    when "notpaid"
+      content_tag(:span, "Pte. de pago", class: "label label-sm label-default")
+    end
+  end
 end

+ 6 - 0
app/helpers/reports_helper.rb

@@ -0,0 +1,6 @@
+module ReportsHelper
+  def calculate_restock(available)
+    stock = (available.stock_max - available.stock)
+    stock
+  end
+end

+ 2 - 0
app/helpers/supports_helper.rb

@@ -0,0 +1,2 @@
+module SupportsHelper
+end

+ 23 - 0
app/helpers/users_helper.rb

@@ -1,2 +1,25 @@
 module UsersHelper
+  def usertype(user)
+    case user.usertype
+    when "SS" then
+      content_tag(:span, "Super Administrador", class: "label label-danger")
+    when "A" then
+      content_tag(:span, "Administrador", class: "label label-danger", style: "font-size:100%")
+    when "G" then
+      content_tag(:span, "Gerente", class: "label label-warning", style: "font-size:85%")
+    when "C" then
+      content_tag(:span, "Caja", class: "label label-info")
+    when "S" then
+      content_tag(:span, "Almacenista", class: "label label-info")
+    end
+  end
+
+  def user_status(user)
+    case user.status
+    when "active" then
+      content_tag(:span, "", class: "fa fa-check fa-2 font-green")
+    when "inactive" then
+      content_tag(:span, "", class: "fa fa-times fa-2 font-red")
+    end
+  end
 end

+ 4 - 0
app/mailers/application_mailer.rb

@@ -0,0 +1,4 @@
+class ApplicationMailer < ActionMailer::Base
+  default from: "from@example.com"
+  layout 'mailer'
+end

+ 14 - 0
app/mailers/support_mailer.rb

@@ -0,0 +1,14 @@
+class SupportMailer < ApplicationMailer
+  default from: 'noreply@sml.mx'
+
+  def contact_support(params, user)
+    @user = user
+    @error_descriptor = params[:error_descriptor]
+    @comments = params[:comments]
+    @usertype = params[:usertype]
+    @sucursal = params[:sucursal]
+    mail(to: Rails.application.config.support_mails, subject: 'Soporte Técnico POS Boutique') do |format|
+      format.html
+    end
+  end
+end

+ 9 - 5
app/models/ability.rb

@@ -32,14 +32,14 @@ class Ability
 
     user ||= User.new
 
-    if user.usertype == "A"
+    if user.usertype == "A" || user.usertype == "SS"
       # Cajas registradoras
-      can :read, [CashRegister, Purchase, PaymentMethod, ProductsReturn]
+      can :read, [CashRegister, Purchase, PaymentMethod, ProductsReturn, CashOut]
       # Categorias
-      can :manage, [Category, Customer, BillingInformation, Expensesconcept, Pointsale, Product, Supplier, Unit, Sale, PosConfig, Purchase, SpecialPrice, ProductWaste, Seller, CashOut, Transfer, Expense, User, Warehouse, Commission, Sellerscommission]
-
+      can :manage, [Category, Customer, BillingInformation, Expensesconcept, Pointsale, Product, Supplier, Unit, Sale, PosConfig, Purchase, SpecialPrice, ProductWaste, Seller, Transfer, Expense, User, Warehouse, Commission, Sellerscommission]
+      can [:opened_cash_registers, :find_cash_outs_by_date], CashOut
       cannot [:create, :delete, :liquidate_reserve], Sale
-
+      cannot :create, ProductWaste
     elsif user.usertype == "G"
       # Cajas registradoras
       can :manage, [CashRegister, Purchase, Product, PrePurchase, Seller, Sale, Expense, ProductWaste, Transfer, OpenCashRegister, CashOut, Supplier, Customer, Credit, CreditPayment, Commission, Sellerscommission, ProductsReturn, Category]
@@ -48,6 +48,8 @@ class Ability
       # Clientes
       can :cru, [Customer, BillingInformation, Pointsale, User, Warehouse, Credit, CreditPayment, Commission, Sellerscommission]
 
+      cannot :opened_cash_registers, CashOut
+
     elsif user.usertype == "C"
       # Cajas registradoras
       can :read, [Product, Pointsale, Customer, BillingInformation, Seller, SpecialPrice, Expensesconcept, Credit, CreditPayment]
@@ -56,6 +58,8 @@ class Ability
 
       can :manage, [CashRegister, PreSale, OpenCashRegister, Sale, Customer, Credit, CreditPayment, CashOut, Expense, Transfer, ProductsReturn, ProductWaste]
 
+      cannot :opened_cash_registers, CashOut
+
     elsif user.usertype == "S"
       can :read, [CashRegister, Product, Pointsale, Customer, BillingInformation, Seller, SpecialPrice, Expensesconcept]
 

+ 0 - 2
app/models/available_product.rb

@@ -1,8 +1,6 @@
 class AvailableProduct < ActiveRecord::Base
-
   belongs_to :product
   belongs_to :pointsale
-
   has_many :categories, :through => :product
 
   audited

+ 16 - 24
app/models/cash_out.rb

@@ -1,26 +1,18 @@
 class CashOut < ActiveRecord::Base
-	belongs_to :user, :class_name => 'User'
-	belongs_to :received_by, :class_name => 'User'
-	belongs_to :open_cash_register
-	has_many :cash_out_details
-
-	has_one :cash_register, :through => :open_cash_register
-	has_one :pointsale, :through => :cash_register
-
-	##--- Llevar registro de Actividad del usuario
-	audited
-
-  	accepts_nested_attributes_for :cash_out_details
-  	# accepts_nested_attributes_for :cash_out_details,
-  	# 	:reject_if => proc { |att| att['received_by_id'].blank? }
-
-
-	validates :received_cash, presence: { message: "Debe indicar el efectivo a retirar." }, :on => [:create]
-	validates :cash_fund, presence: { message: "Debe indicar el fondo de caja." }, :on => [:create]
-	validates :received_by_id, presence: { message: "Debe seleccionar quien recibe el dinero del corte." }, :on => [:create]
-
-
-	validates_associated :cash_out_details
-
-
+  belongs_to :user, class_name: 'User'
+  belongs_to :received_by, class_name: 'User'
+  belongs_to :open_cash_register
+  has_many :cash_out_details
+
+  has_one :cash_register, through: :open_cash_register
+  has_one :pointsale, through: :cash_register
+
+  ##--- Llevar registro de Actividad del usuario
+  audited
+
+  accepts_nested_attributes_for :cash_out_details
+  validates :received_cash, presence: { message: "Debe indicar el efectivo a retirar." }, on: [:create]
+  validates :cash_fund, presence: { message: "Debe indicar el fondo de caja." }, on: [:create]
+  validates :received_by_id, presence: { message: "Debe seleccionar quién recibe el dinero del corte." }, on: [:create]
+  validates_associated :cash_out_details
 end

+ 14 - 15
app/models/cash_register.rb

@@ -1,18 +1,17 @@
 class CashRegister < ActiveRecord::Base
-    ## Associaciones
-    belongs_to :pointsale
-    has_many :open_cash_registers
-    has_many :cash_registers_moves, :through => :open_cash_registers
-    has_many :cash_outs, :through => :open_cash_registers
-    
-	enum status: [ :erased, :active, :inactive ]
-    enum main: [:no, :yes]
-	##--- Validaciones previas de guardar
-    validates :name , presence: { message: "Debe capturar el nombre de la caja registradora." }
-    validates :pointsale_id , presence: { message: "Debe seleccionar un punto de venta." }
+  ## Associaciones
+  belongs_to :pointsale
+  has_many :open_cash_registers
+  has_many :cash_registers_moves, through: :open_cash_registers
+  has_many :cash_outs, through: :open_cash_registers
 
-	##--- Tipo de vistas / consultas
-	scope :vigentes, -> { where("status != 0").order(" status ASC, name ASC") }
-	scope :activos, -> { where( "status = 1").order(" name ASC") }
-    
+  enum status: [:erased, :active, :inactive]
+  enum main: [:no, :yes]
+  ##--- Validaciones previas de guardar
+  validates :name, presence: { message: "Debe capturar el nombre de la caja registradora." }
+  validates :pointsale_id, presence: { message: "Debe seleccionar un punto de venta." }
+
+  ##--- Tipo de vistas / consultas
+  scope :vigentes, -> { where.not(status: 0).order("status ASC, name ASC") }
+  scope :activos, -> { where(status: 1).order("name ASC") }
 end

+ 20 - 20
app/models/open_cash_register.rb

@@ -1,26 +1,26 @@
 class OpenCashRegister < ActiveRecord::Base
-	belongs_to :cash_register
-	belongs_to :user
-	has_many :cash_registers_moves
-	has_many :sales
-	has_many :sales_details, :through => :sales
-	has_many :products, :through => :sales_details
-	has_many :categories, :through => :products
-	has_many :expenses
-	has_many :pre_sales
-	has_many :cash_outs
-	has_one :pointsale, :through => :cash_register
+  belongs_to :cash_register
+  belongs_to :user
+  has_many :cash_registers_moves
+  has_many :sales
+  has_many :sales_details, through: :sales
+  has_many :products, through: :sales_details
+  has_many :categories, through: :products
+  has_many :expenses
+  has_many :pre_sales
+  has_many :cash_outs
+  has_one :pointsale, through: :cash_register
 
-  	##--- Llevar registro de Actividad del usuario
-	audited
+  ##--- Llevar registro de Actividad del usuario
+  audited
 
-	enum status: [:open, :closed]
+  enum status: [:open, :closed]
 
-	scope :abiertas, -> { where( "open_cash_registers.status = 0") }
+  scope :abiertas, -> { where("open_cash_registers.status = ?", 0) }
 
-	def self.get_pointsale(id, option)
-		if option == "open_cash_register"
-			Pointsale.find(CashRegister.find(OpenCashRegister.find(id).cash_register_id).pointsale_id)
-		end
-	end
+  def self.get_pointsale(id, option)
+    if option == "open_cash_register"
+      Pointsale.find(CashRegister.find(OpenCashRegister.find(id).cash_register_id).pointsale_id)
+    end
+  end
 end

+ 5 - 7
app/models/pointsale.rb

@@ -39,19 +39,17 @@ class Pointsale < ActiveRecord::Base
 
   ##--- Validaciones previas de guardar
   validates :name, presence: { message: "Debe capturar el nombre del punto de venta." }, unless: :skip_name_validation
-  validates :prefix, presence: { message: "Debe indicar el prefijo del punto de venta." }, length: { maximum: 3, too_long: "El maximo de caracteres debe ser %{count}.", minimum: 3, too_short: "El minimo de caracteres debe ser %{count}." }, uniqueness: { message: "El prefijo ya fue utilizado, favor de especificar otro." }
+  validates :prefix, presence: { message: "Debe indicar el prefijo del punto de venta." }, length: { maximum: 3, too_long: "El máximo de caracteres debe ser %{count}.", minimum: 3, too_short: "El mínimo de caracteres debe ser %{count}." }, uniqueness: { message: "El prefijo ya fue utilizado, favor de especificar otro." }
   # validates_attachment_content_type :img_pointsale, :content_type => /\Aimage\/.*\Z/
 
   ##--- Tipo de vistas / consultas
-  scope :vigentes, -> { where("status != 0").order("status ASC, name ASC") }
-  scope :activos, -> { where("status = 1").order("name ASC") }
+  scope :vigentes, -> { where.not(status: 0).order("status ASC, name ASC") }
+  scope :activos, -> { where(status: 1).order("name ASC") }
   scope :ignore_current, ->(pointsale_id) { where.not(id: pointsale_id) }
   # def has_stock
 
-  def total_products(pointsale_id)
-    unless pointsale_id.nil?
-      Pointsale.find(pointsale_id).products.where("stock > 0").sum(:stock).to_i
-    end
+  def total_products
+    products.where("stock > 0").sum(:stock).to_i
   end
 
   def self.get_pointsale(id, option)

+ 5 - 5
app/models/pos_config.rb

@@ -1,14 +1,14 @@
 class PosConfig < ActiveRecord::Base
-
-  	##--- Llevar registro de Actividad del usuario
+  ##--- Llevar registro de Actividad del usuario
 	audited
 
+	attr_accessor :skip_haggle_percent
+
 	mount_uploader :ticket_img, ImageUploader
 
 	#has_attached_file :ticket_img, :styles => { :medium => "250x80>", :thumb => "50x50>" }, :default_url => "/images/:style/missing.png"
 	#validates_attachment_content_type :ticket_img, :content_type => /\Aimage\/.*\Z/
 
-
 	validates_presence_of :cancel_partial_payment, message: "Debe especificar los días para cancelar un abono."
 	validates_presence_of :refund_sale, message: "Debe especificar los días para la devolución de una venta."
 	validates_presence_of :days_cancel_sale, message: "Debe especificar los días para modificar/cancelar una venta."
@@ -18,7 +18,7 @@ class PosConfig < ActiveRecord::Base
 	validates_presence_of :gain_margin, message: "Debe especificar el porcentaje de ganancia tendrán a los productos."
 	validates_presence_of :reserve_sale_percent, message: "Debe especificar el porcentaje para realizar un apartado."
 	validates_presence_of :days_cancel_reserved, message: "Debe especificar los días para cancelar un apartado."
-	validates_presence_of :haggle_in_sale_percent, message: "Debe especificar el porcentaje regateo a aplicar en las ventas."
+	# validates_presence_of :haggle_in_sale_percent, message: "Debe especificar el porcentaje regateo a aplicar en las ventas.", unless: :skip_haggle_percent
+	validates_numericality_of :haggle_in_sale_percent, greater_than: 0.00, message: "El porcentaje de regateo debe ser mayor a 0", unless: :skip_haggle_percent
 	validates_presence_of :commission_percent, message: "Debe especificar el porcentaje por comisión de venta."
-
 end

+ 22 - 14
app/models/product.rb

@@ -50,14 +50,14 @@ class Product < ActiveRecord::Base
   end
 
   ##--- Tipo de vistas / consultas
-  scope :vigentes, -> { where("status != 0").order(" status ASC, name ASC") }
-  scope :activos, -> { where("status = 1").order(" name ASC") }
-  scope :activos_children, -> { where("status = 1 and is_parent = false ").order("products.name ASC") }
-  scope :vigentes_parents, -> { where("status != 0 and parent_id IS NULL ").order(" status ASC, name ASC") }
-  scope :name_sku_barcode_like, ->(name) { where("status = 1 and is_parent = false and (name ilike ? or sku ilike ? or barcode ilike ?)", "%#{name}%", "%#{name}%", "%#{name}%").order("name") }
-  scope :name_sku_barcode_attribute_like, ->(name, attributes_string) { where("status = 1 and is_parent = false and (name ilike ? or sku ilike ? or barcode ilike ?) #{attributes_string}", "%#{name}%", "%#{name}%", "%#{name}%").order("name") }
+  scope :vigentes, -> { where.not(products: { status: 0 }).order(" products.status ASC, products.name ASC") }
+  scope :activos, -> { where(status: 1).order("products.name ASC") }
+  scope :activos_children, -> { activos.where(is_parent: false).order("products.name ASC") }
+  scope :vigentes_parents, -> { vigentes.where("parent_id IS NULL") }
+  scope :name_sku_barcode_like, ->(name) { activos.where("is_parent = ? and (name ilike ? or sku ilike ? or barcode ilike ?)", false, "%#{name}%", "%#{name}%", "%#{name}%") }
+  scope :name_sku_barcode_attribute_like, ->(name, attributes_string) { activos.where("is_parent = ? and (name ilike ? or sku ilike ? or barcode ilike ?) #{attributes_string}", false, "%#{name}%", "%#{name}%", "%#{name}%") }
   # para special_prices
-  scope :name_sku_barcode_like_sp, ->(name) { where("status = 1 and is_parent = true and (name ilike ? or sku ilike ? or barcode ilike ?)", "%#{name}%", "%#{name}%", "%#{name}%").order("name") }
+  scope :name_sku_barcode_like_sp, ->(name) { activos.where("is_parent = ? and (name ilike ? or sku ilike ? or barcode ilike ?)", true, "%#{name}%", "%#{name}%", "%#{name}%") }
 
   def name_with_sku
     sku.to_s + " - " + name.to_s
@@ -67,6 +67,13 @@ class Product < ActiveRecord::Base
     sku.to_s + " | " + name.to_s + " | " + display_attributes.to_s
   end
 
+  def full_display
+    show_name = name + "\n" + "SKU: " + sku + "\n"
+    show_name += "\n" + display_attributes.to_s if parent_id.present?
+    show_name += " Código de barras: " + barcode if parent_id.present? && barcode.present?
+    show_name
+  end
+
   def stock_in_pointsale(pointsale_id)
     stock = 0
     # checar si hay existencias en los almacenes.
@@ -118,8 +125,9 @@ class Product < ActiveRecord::Base
   end
 
   def get_price_sale(pointsale_id)
-    if pointsale_id != 0 && available_in_pointsale?(pointsale_id) && !get_available_in_pointsale(pointsale_id).price_sale.nil?
-      get_available_in_pointsale(pointsale_id).price_sale
+    available = get_available_in_pointsale(pointsale_id)
+    if available.present? && available.price_sale.present?
+      available.price_sale
     else
       price_sale
     end
@@ -382,14 +390,14 @@ class Product < ActiveRecord::Base
       end_period = Date.current.end_of_month
     end
 
-    if user.usertype == 'A'
+    if user.usertype == "A" || user.usertype == "SS"
       quantities_top_products = SalesDetail.activos.joins(:sale, :product).where("sales.date_sale between ? and ?", beg_period, end_period).group('products.name').order('sum_quantity desc').limit(10).sum(:quantity)
       total_top_products = SalesDetail.activos.joins(:sale).where('sales.date_sale between ? and ?', beg_period, end_period).order('sum_quantity desc').limit(10).sum(:quantity)
       total_sold = SalesDetail.activos.joins(:sale).where('sales.date_sale between ? and ?', beg_period, end_period).sum(:quantity)
     elsif user.usertype == 'G'
-      quantities_top_products = user.pointsale.sales_details.joins(:sale, :product).where("sales.status != 1 and sales.date_sale between ? and ?", beg_period, end_period).group('products.name').order('sum_quantity desc').limit(10).sum(:quantity)
-      total_top_products = user.pointsale.sales_details.joins(:sale).where('sales.status != 1 and sales.date_sale between ? and ?', beg_period, end_period).order('sum_quantity desc').limit(10).sum(:quantity)
-      total_sold = user.pointsale.sales_details.joins(:sale).where('sales.status != 1 and sales.date_sale between ? and ?', beg_period, end_period).sum(:quantity)
+      quantities_top_products = user.pointsale.sales_details.joins(:sale, :product).where("sales.status != ? and sales.date_sale between ? and ?", 1, beg_period, end_period).group('products.name').order('sum_quantity desc').limit(10).sum(:quantity)
+      total_top_products = user.pointsale.sales_details.joins(:sale).where('sales.status != ? and sales.date_sale between ? and ?', 1, beg_period, end_period).order('sum_quantity desc').limit(10).sum(:quantity)
+      total_sold = user.pointsale.sales_details.joins(:sale).where('sales.status != ? and sales.date_sale between ? and ?', 1, beg_period, end_period).sum(:quantity)
     end
 
     others = total_sold - total_top_products
@@ -400,7 +408,7 @@ class Product < ActiveRecord::Base
   end
 
   def get_available_children(just_pointsales)
-    children = Product.where("parent_id = ? and status != 0 ", id).pluck(:id)
+    children = Product.vigentes.where("parent_id = ?", id).pluck(:id)
     if just_pointsales
       AvailableProduct.where("product_id IN (?)", children).joins(:pointsale).select(:pointsale_id, :name).distinct(:pointsale_id)
     else

+ 12 - 12
app/models/product_waste.rb

@@ -1,18 +1,18 @@
 class ProductWaste < ActiveRecord::Base
-	belongs_to :product
-	belongs_to :user
-	belongs_to :pointsale
-	belongs_to :warehouse
-	belongs_to :products_return_in
+  belongs_to :product
+  belongs_to :user
+  belongs_to :pointsale
+  belongs_to :warehouse
+  belongs_to :products_return_in
 
-  	##--- Llevar registro de Actividad del usuario
-	audited
+  ##--- Llevar registro de Actividad del usuario
+  audited
 
-	validates :product_id , :presence => { message: "Debe seleccionar producto." }, :on => [:create]
-	validates :quantity , :presence => { message: "Debe indicar cantidad." }, :on => [:create]
-	validates :reason , :presence => { message: "Debe indicar el motivo." }, :on => [:create]
+  validates :product_id, presence: { message: "Debe seleccionar producto." }, on: [:create]
+  validates :quantity, presence: { message: "Debe indicar cantidad." }, on: [:create]
+  validates :reason, presence: { message: "Debe indicar el motivo." }, on: [:create]
 
-	enum status: [:active, :inactive ]
+  enum status: [:active, :inactive]
 
-	scope :activos, -> { where( "status = 0").order(" id DESC") }
+  scope :activos, -> { where(status: 0).order("id DESC") }
 end

+ 1 - 1
app/models/seller.rb

@@ -15,7 +15,7 @@ class Seller < ActiveRecord::Base
   validates :name, presence: { message: "Debe indicar nombre para el vendedor." }, on: [:create, :update]
   validates :last_name, presence: { message: "Debe indicar apellido para el vendedor." }, on: [:create, :update]
 
-  scope :vigentes, -> { where("status != 0") }
+  scope :vigentes, -> { where.not(status: 0) }
 
   ##--- Funciones personalizadas
   def full_name

+ 2 - 0
app/models/user.rb

@@ -38,6 +38,8 @@ class User < ActiveRecord::Base
 
   validates :userid, uniqueness: { message: "El usuario ya fue utilizado, favor de especificar otro." }
 
+  scope :vigentes, -> { where.not(status: 0).order(userid: :asc) }
+
   def full_name
     "#{first_name} #{last_name}"
   end

+ 4 - 5
app/views/available_products/_edit_price.html.erb

@@ -7,9 +7,9 @@
 	<% end %>
 	<div class="form-body">
 		<div class="row">
-			
+
 			<div class="col-md-12">
-				<% if current_user.usertype == "A" %>
+				<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
 				<p> Punto de venta: <%= @available_product.pointsale.name %></p>
 				<% end %>
 				<p> Producto: <%= @product.name %> con precio de venta (base) de $<%= @product.price_sale %>
@@ -31,13 +31,12 @@
 		</div>
 	</div>
 	<div class="form-actions">
-	    
 		<div class="row">
 			<div class="col-md-offset-3 col-md-9">
-				<%= f.submit 'Actualizar precio', {:class=>"btn green"} %> 
+				<%= f.submit 'Actualizar precio', {:class=>"btn green"} %>
 				<button type="button" data-dismiss="modal" class="btn">Cancelar</button>
 			</div>
 		</div>
 	</div>
 </div>
-<% end %>
+<% end %>

+ 49 - 52
app/views/available_products/_form.html.erb

@@ -1,62 +1,62 @@
-<%= form_for(AvailableProduct.new, :html => {:class=>"form-horizontal", :id=> "available_products_form"}) do |f| %>
-  <div class="portlet-body form">
-    <div id="error_explanation"></div>
-
-      <table class="table table-striped table-bordered table-hover stock-table" id="pointsale_stock" data-source="<%= @showcolumns == 'initial' ?  products_initial_stock_path(@location_id, :format => 'json') : products_stock_path(@location_id, :format => 'json') %>">
-        <thead>
-          <tr>
-            <th class="text-center"><input name="select_all" value="1" id="select-all" type="checkbox" /></th>
-            <th>Imagen</th>
-            <th>SKU</th>
-            <th>Producto</th>
-            <th>Línea</th>
-            <th>Sublínea</th>
-            <% case @showcolumns
-              when "initial" %>
-                <th>Stock inicial</th>
-            <% when "minMax" %>
-                <th>Stock mínimo</th>
-                <th>Stock máximo</th>
-            <% end %>
-          </tr>
-        </thead>
-        <tbody>
-        </tbody>
-      </table>
-    </div>
+<div class="portlet-body form">
+  <div id="error_explanation"></div>
+    <table class="table table-striped table-bordered table-hover stock-table" id="pointsale_stock" data-source="<%= @showcolumns == 'initial' ?  products_initial_stock_path(@location_id, format: 'json') : products_stock_path(@location_id, format: 'json') %>">
+      <thead>
+        <tr>
+          <th class="text-center"><input name="select_all" value="1" id="select-all" type="checkbox" /></th>
+          <th>Imagen</th>
+          <th>SKU</th>
+          <th>Producto</th>
+          <th>Línea</th>
+          <th>Sublínea</th>
+          <% if @showcolumns == "initial" %>
+            <th>Stock inicial</th>
+          <% elsif @showcolumns == "minMax" %>
+            <th>Stock mínimo</th>
+            <th>Stock máximo</th>
+          <% end %>
+        </tr>
+      </thead>
+      <tbody>
+      </tbody>
+    </table>
   </div>
-<% end %>
+</div>
 
 <script type="text/javascript">
   var rows_selected = [];
   var tableClass = '.stock-table';
   var columns = "<%= @column_definition %>";
-  var tableColumns = JSON.parse(columns.replace(/&quot;/g,'"'));
+  var tableColumns = JSON.parse(columns.replace(/&quot;/g, '"'));
   var order = 3;
   var extraData = {};
 
+  $('#pointsale').on('change', function(e) {
+    $('#pointsale_stock').DataTable().draw();
+  });
+
   tableWithCheckboxAjax.init(tableClass, tableColumns, order, extraData, rows_selected);
 
-// $(document).on("page:change", function() {
-//   App.init();
-// });
+  // $(document).on("page:change", function() {
+  //   App.init();
+  // });
 
-toastr.options = {
-  "closeButton": false,
-  "debug": false,
-  "positionClass": "toast-bottom-right",
-  "onclick": null,
-  "showDuration": "1000",
-  "hideDuration": "1000",
-  "timeOut": "5000",
-  "extendedTimeOut": "1000",
-  "showEasing": "swing",
-  "hideEasing": "linear",
-  "showMethod": "fadeIn",
-  "hideMethod": "fadeOut"
-}
+  toastr.options = {
+    "closeButton": false,
+    "debug": false,
+    "positionClass": "toast-bottom-right",
+    "onclick": null,
+    "showDuration": "1000",
+    "hideDuration": "1000",
+    "timeOut": "5000",
+    "extendedTimeOut": "1000",
+    "showEasing": "swing",
+    "hideEasing": "linear",
+    "showMethod": "fadeIn",
+    "hideMethod": "fadeOut"
+  }
 
-function updateStock() {
+  function updateStock() {
   var min = parseInt($('#min_stock_general').val());
   var max = parseInt($('#max_stock_general').val());
   // checar por campos vacios
@@ -100,9 +100,9 @@ function updateStock() {
         });
     }
   }
-}
+  }
 
-function initialStock() {
+  function initialStock() {
   var initialStock = parseInt($('#initial_stock_input').val());
   if (initialStock || initialStock == 0) {
     if(rows_selected.length > 0) {
@@ -136,8 +136,5 @@ function initialStock() {
   } else {
     toastr["error"]("Error, NO puede quedar vacio el campo de stock inicial");
   }
-}
+  }
 </script>
-
-
-

+ 83 - 89
app/views/available_products/index.html.erb

@@ -1,100 +1,94 @@
-    <!-- BEGIN CONTAINER -->
-    <div class="page-container">
-      <!-- BEGIN CONTENT -->
-      <div class="page-content-wrapper">
-        <!-- BEGIN CONTENT BODY -->
-        <!-- BEGIN PAGE HEAD-->
-        <div class="page-head">
-          <div class="container-fluid">
-            <!-- BEGIN PAGE TITLE -->
-            <div class="page-title">
-              <h1>Productos disponibles</h1>
+<!-- BEGIN CONTAINER -->
+<div class="page-container">
+  <!-- BEGIN CONTENT -->
+  <div class="page-content-wrapper">
+    <!-- BEGIN CONTENT BODY -->
+    <!-- BEGIN PAGE HEAD-->
+    <div class="page-head">
+      <div class="container-fluid">
+        <!-- BEGIN PAGE TITLE -->
+        <div class="page-title">
+          <h1>Productos disponibles</h1>
+        </div>
+        <!-- END PAGE TITLE -->
+      </div>
+    </div>
+    <!-- END PAGE HEAD-->
+    <!-- BEGIN PAGE CONTENT BODY -->
+    <div class="page-content">
+      <div class="container-fluid">
+        <!-- BEGIN PAGE BREADCRUMBS -->
+        <ul class="page-breadcrumb breadcrumb">
+        <li>
+          <a href="/">Inicio</a>
+          <i class="fa fa-circle"></i>
+        </li>
+        <li>
+          <span> </span>
+        </li>
+      </ul>
+        <!-- END PAGE BREADCRUMBS -->
+        <!-- BEGIN PAGE CONTENT INNER -->
+      <div class="page-content-inner">
+        <div id="notice">
+          <% if success %>
+            <div class="alert alert-success">
+              <p><%= success %></p>
             </div>
-            <!-- END PAGE TITLE -->
-          </div>
+          <% elsif warning %>
+            <div class="alert alert-warning">
+              <p><%= warning %></p>
+            </div>
+          <% end %>
         </div>
-        <!-- END PAGE HEAD-->
-        <!-- BEGIN PAGE CONTENT BODY -->
-        <div class="page-content">
-          <div class="container-fluid">
-            <!-- BEGIN PAGE BREADCRUMBS -->
-            <ul class="page-breadcrumb breadcrumb">
-            <li>
-              <a href="/">Inicio</a>
-              <i class="fa fa-circle"></i>
-            </li>
-            <li>
-              <span> </span>
-            </li>
-          </ul> 
-            <!-- END PAGE BREADCRUMBS -->
-            <!-- BEGIN PAGE CONTENT INNER -->
-            <div class="page-content-inner">
-              <div id="notice">
-                <% if success %> 
-                <div class="alert alert-success">
-                  <p><%= success %></p>
-                </div>
-                <% elsif warning %>
-                <div class="alert alert-warning">
-                  <p><%= warning %></p>
+        <div class="row">
+          <%= form_for(@pointsale, html: { class: "form-horizontal" }) do |f| %>
+            <div class="col-md-6">
+              <div class="portlet light ">
+                <div class="portlet-title">
+                  <div class="caption">
+                    <i class="fa fa-list "></i>
+                    <span class="caption-subject bold uppercase">Productos disponibles</span>
+                  </div>
+                  <div class="actions">
+                  </div>
                 </div>
-                <% end %>
-              </div>
-              <div class="row">
-                <%= form_for(@pointsale, :html => {:class=>"form-horizontal"}) do |f| %>
-                <div class="col-md-6">
-                  <div class="portlet light ">
-                    <div class="portlet-title">
-                      <div class="caption">
-                        <i class="fa fa-list "></i>
-                        <span class="caption-subject bold uppercase">Productos disponibles</span>
-                      </div>
-                      <div class="actions">
-                        
-                      </div>
-                    </div>
-                    <div class="portlet-body">
-                      <div class="note note-info">
-                          <h4 class="block">Lista de productos disponibles</h4>
-                          <p> En esta lista se muestran todos los productos disponibles para su venta en forma general, dentro de la cuenta de administración. </p>
-                      </div>
-                      <table class="table table-striped table-bordered table-hover tablechecks">
-                        <thead>
-                          <tr>
-                            <th> <input type="checkbox" class="group-checkable" data-set=".tablechecks .checkboxes" /> </th>
-                            <th>SKU</th>
-                            <th>Producto</th>
-                            <th>Categorias</th>
-                            
-                          </tr>
-                        </thead>
-                        <tbody>
-                          <% @products.each do |product| %>
-                            <tr>  
-                              <td> <input type="checkbox" class="checkboxes" value="1" /> </td>
-                              <td><%= product.sku %></td>
-                              <td><%= product.name %> | <%= product.display_attributes %> </td>
-                              <td><%= product.categories.map { |cat| cat.category }.join(", ")  %></td>
-                              
-                            </tr>
-                          <% end %>
-                        </tbody>
-                      </table>
-                    </div>
+                <div class="portlet-body">
+                  <div class="note note-info">
+                    <h4 class="block">Lista de productos disponibles</h4>
+                    <p> En esta lista se muestran todos los productos disponibles para su venta en forma general, dentro de la cuenta de administración. </p>
                   </div>
+                  <table class="table table-striped table-bordered table-hover tablechecks">
+                    <thead>
+                      <tr>
+                        <th> <input type="checkbox" class="group-checkable" data-set=".tablechecks .checkboxes" /> </th>
+                        <th>SKU</th>
+                        <th>Producto</th>
+                        <th>Categorias</th>
+                      </tr>
+                    </thead>
+                    <tbody>
+                      <% @products.each do |product| %>
+                        <tr>
+                          <td> <input type="checkbox" class="checkboxes" value="1" /> </td>
+                          <td><%= product.sku %></td>
+                          <td><%= product.name %> | <%= product.display_attributes %> </td>
+                          <td><%= product.categories.map { |cat| cat.category }.join(", ") %></td>
+                        </tr>
+                      <% end %>
+                    </tbody>
+                  </table>
                 </div>
-                <% end %>
               </div>
             </div>
-            <!-- END PAGE CONTENT INNER -->
+            <% end %>
           </div>
         </div>
-        <!-- END PAGE CONTENT BODY -->
-        <!-- END CONTENT BODY -->
+        <!-- END PAGE CONTENT INNER -->
       </div>
-      <!-- END CONTENT -->
     </div>
-    <!-- END CONTAINER -->
-
-
+    <!-- END PAGE CONTENT BODY -->
+    <!-- END CONTENT BODY -->
+  </div>
+  <!-- END CONTENT -->
+</div>

+ 23 - 20
app/views/available_products/initial_stock.html.erb

@@ -17,36 +17,42 @@
     <!-- BEGIN PAGE CONTENT BODY -->
     <div class="page-content">
       <div class="container-fluid">
-        <%= link_to  root_path, {:class=>"btn blue-hoki pull-right margin-bottom-10"} do %>  <i class="fa fa-angle-left "></i> Regresar
-        <% end %>
         <!-- END PAGE BREADCRUMBS -->
+        <ul class="page-breadcrumb breadcrumb">
+          <%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
+        </ul>
         <!-- BEGIN PAGE CONTENT INNER -->
         <div class="page-content-inner">
           <div id="notice"><%= notice %></div>
           <div class="row">
             <div class="col-md-12">
-              <div class="portlet light">  
+              <div class="portlet light">
                 <div class="portlet-body form">
-                  <div id="error_explanation"></div> 
-
+                  <div id="error_explanation"></div>
                   <!-- lista de productos -->
                   <h4 class="form-section"> Lista de productos</h4>
                   <div class="portlet-body">
-                    <div class="row"> 
+                    <div class="row">
+                      <% unless current_user.usertype == "G" %>
+                        <%= label_tag :pointsale, "Puntos de venta", class: "control-label col-md-1 col-sm-2" %>
+                        <div class="col-md-3 col-sm-4">
+                          <%= select_tag "pointsale", options_from_collection_for_select(@pointsales, :id, :name), class: "form-control input-medium" %>
+                        </div>
+                      <% end %>
                       <!-- stock minimo para los seleccionados -->
-                        <div class="col-md-8">
-                          <div class="form-group">
-                            <label class="col-md-1"> Stock inicial </label>          
-                            <div class="col-md-2">
-                              <input class="form-control" type="number" min="0" id="initial_stock_input">
-                            </div>
-                            <div class="col-md-2">
-                              <button type="button" class="btn btn-success" onclick="initialStock()"><i class="fa fa-save"></i>&nbsp&nbspGuardar cambios</button>                 
-                            </div>
-                          </div> 
+                      <div class="col-md-6 col-sm-6">
+                        <div class="form-group">
+                          <label class="col-md-3 col-sm-3"> Stock inicial </label>
+                          <div class="col-md-2 col-sm-3">
+                            <input class="form-control input-xsmall" type="number" min="0" id="initial_stock_input">
+                          </div>
+                          <div class="col-md-4 col-sm-5">
+                            <button type="button" class="btn btn-success" onclick="initialStock()"><i class="fa fa-save"></i>&nbsp&nbspGuardar cambios</button>
+                          </div>
                         </div>
+                      </div>
                     </div>
-                    <h4 class="form-section" style="margin-top: 5px; margin-bottom: 20px"></h4>   
+                    <h4 class="form-section" style="margin-top: 5px; margin-bottom: 20px"></h4>
                   </div>
                 </div>
                 <%= render 'form' %>
@@ -62,6 +68,3 @@
   </div>
   <!-- END CONTENT -->
 </div>
-<!-- END CONTAINER -->
-
-

+ 27 - 30
app/views/available_products/stock.html.erb

@@ -17,12 +17,10 @@
     <!-- BEGIN PAGE CONTENT BODY -->
     <div class="page-content">
       <div class="container-fluid">
-        <%= link_to  root_path, {:class=>"btn blue-hoki pull-right margin-bottom-10"} do %>  <i class="fa fa-angle-left "></i> Regresar
-        <% end %>
         <!-- BEGIN PAGE BREADCRUMBS -->
         <ul class="page-breadcrumb breadcrumb">
           <%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
-      </ul>
+        </ul>
         <!-- END PAGE BREADCRUMBS -->
         <!-- BEGIN PAGE CONTENT INNER -->
         <div class="page-content-inner">
@@ -31,32 +29,34 @@
             <div class="col-md-12">
               <div class="portlet light">
                 <div class="portlet-body form">
-                    <div id="error_explanation"></div>
-
-                    <!-- lista de productos -->
-                    <h4 class="form-section"> Lista de productos</h4>
-                    <div class="portlet-body">
-
-                      <div class="row">
-                        <!-- stock minimo para los seleccionados -->
-                          <div class="col-md-offset-1 col-md-8">
-                            <div class="form-group">
-                              <label class="col-md-1"> Stock Mínimo </label>
-                              <div class="col-md-2">
-                                <input class="form-control" type="number" min="0" id="min_stock_general">
-                              </div>
-                              <label class="col-md-1"> Stock Máximo </label>
-                              <div class="col-md-2">
-                                <input class="form-control" type="number" min="0" id="max_stock_general">
-                              </div>
-                              <div class="col-md-2">
-                                <button type="button" class="btn btn-success" onclick="updateStock()"><i class="fa fa-save"></i>&nbsp&nbspGuardar cambios</button>
-                              </div>
-                            </div>
-                          </div>
+                  <div id="error_explanation"></div>
+                  <!-- lista de productos -->
+                  <h4 class="form-section"> Lista de productos</h4>
+                  <div class="portlet-body">
+                    <div class="row">
+                      <% unless current_user.usertype == "G" %>
+                        <%= label_tag :pointsale, "Puntos de venta", class: "control-label col-md-1 col-sm-2" %>
+                        <div class="col-md-3 col-sm-4">
+                          <%= select_tag "pointsale", options_from_collection_for_select(@pointsales, :id, :name), class: "form-control input-medium" %>
+                        </div>
+                      <% end %>
+                      <!-- stock minimo para los seleccionados -->
+                      <div class="col-md-8">
+                        <label class="col-md-1 col-sm-1"> Stock Mínimo </label>
+                        <div class="col-md-2 col-sm-2">
+                          <input class="form-control" type="number" min="0" id="min_stock_general">
+                        </div>
+                        <label class="col-md-1 col-sm-1"> Stock Máximo </label>
+                        <div class="col-md-2 col-sm-2">
+                          <input class="form-control" type="number" min="0" id="max_stock_general">
+                        </div>
+                        <div class="col-md-2 col-sm-3">
+                          <button type="button" class="btn btn-success" onclick="updateStock()"><i class="fa fa-save"></i>&nbsp&nbspGuardar cambios</button>
+                        </div>
                       </div>
-                      <h4 class="form-section" style="margin-top: 5px; margin-bottom: 20px"></h4>
                     </div>
+                    <h4 class="form-section" style="margin-top: 5px; margin-bottom: 20px"></h4>
+                  </div>
                 </div>
                 <%= render 'form' %>
               </div>
@@ -71,6 +71,3 @@
   </div>
   <!-- END CONTENT -->
 </div>
-<!-- END CONTAINER -->
-
-

+ 3 - 5
app/views/available_products/stock_by_pointsale.html.erb

@@ -59,7 +59,7 @@
 														<!-- sub- categoria -->
 														<%= label :sub_category, "", {:class=>"col-md-1 control-label"} do %>Sublínea <% end %>
 														<div class="col-md-3 select2-bootstrap-prepend">
-															<%= select_tag "sub_category", options_from_collection_for_select(Category.activos.where('parent_id != 0'), :id, :category), :include_blank => "Todas",  class: "form-control select2 clereable" %>
+															<%= select_tag "sub_category", options_from_collection_for_select(Category.activos.where('parent_id != 0'), :id, :category), :include_blank => "Todas", class: "form-control select2 clereable" %>
 														</div>
 													</div>
 												</div>
@@ -71,7 +71,7 @@
 														<div class="uppercase font-hg font-blue-sharp" id="total_prods"></div>
 													</div>
 												</div>
-												<% if current_user.usertype == 'A' %>
+												<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
 													<div class="col-md-3 col-sm-4 col-xs-6 ">
 														<div class="text-center well" id="container_total_invested" style="margin-bottom: 0px">
 															<div class="font-grey-mint font-sm">Total invertido en pesos </div>
@@ -129,8 +129,6 @@
 		if (sub_category) { uri += '&sub_category=' + sub_category; }
 		if (search) { uri += '&search=' + encodeURIComponent(search); }
 
-		window.open('/print_stock_by_pointsale.pdf?' + uri, 'New tab', '' );
-
+		window.open('/print_stock_by_pointsale.pdf?' + uri, 'New tab', '');
 	}
 </script>
-

+ 8 - 5
app/views/cash_outs/_cash_out.html.erb

@@ -1,14 +1,14 @@
 <tr id="cash_out_<%= cash_out.id %>">
   <td><%= cash_out.id %></td>
-  <% if current_user.usertype == "A" %>
+  <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
     <td>
-    <%= OpenCashRegister.get_pointsale(cash_out.open_cash_register_id, "open_cash_register").name %> 
-    </td> 
+    <%= OpenCashRegister.get_pointsale(cash_out.open_cash_register_id, "open_cash_register").name %>
+    </td>
   <% end %>
   <td><%= cash_out.open_cash_register.cash_register.name %> </td>
   <td><%= number_to_currency(cash_out.amount_in, precision: 2) %> </td>
   <td><%= number_to_currency(cash_out.amount_out, precision: 2)  %></td>
-  <td><%= number_to_currency(cash_out.amount_in - cash_out.amount_out, precision: 2)  %></td>  
+  <td><%= number_to_currency(cash_out.amount_in - cash_out.amount_out, precision: 2)  %></td>
   <td><%= l(cash_out.created_at, :format => '%d/%B/%Y') %></td>
   <td><%= cash_out.user.first_name %></td>
   <td><%= (cash_out.received_by.blank? ? "" : cash_out.received_by.first_name) %></td>
@@ -16,5 +16,8 @@
     <%= link_to cash_out, {:class=>"btn btn-icon-only default", :title=>"Ver corte de caja"} do %>
       <i class="fa fa-search"></i>
     <% end %>
+    <%= link_to print_cash_out_receipt_path(cash_out.id, format: 'pdf'), {:class=>"btn btn-icon-only default", :target => "blank"} do %>
+      <i class="fa fa-print"></i>
+    <% end %>
   </td>
-</tr>
+</tr>

+ 10 - 10
app/views/cash_outs/index.html.erb

@@ -44,15 +44,15 @@
                     <span class="caption-subject bold uppercase">Lista de cortes de caja</span>
                   </div>
                    <div class="actions">
-                    <% if current_user.usertype == "G" %>
-                      <% if can? :create, CashOut %>
-                        <%= link_to new_open_cash_register_path, :remote => true, :class => 'btn btn bold green margin-top pull-right', :title => "Abrir caja registradora" do %> Abrir caja <i class="fa fa-plus"></i><% end %> <br>
-                        <%= link_to get_open_cash_registers_path, remote: true, data: { toggle: "modal", target: "#get_open_cash_register" }, :class=>"btn bold green pull-right", :title=>"Realizar corte de caja", :style=> "margin-top:10px"  do %> Realizar corte de caja <i class="fa fa-plus"></i>
+                    <% if can? :create, OpenCashRegister %>
+                      <%= link_to new_open_cash_register_path, remote: true, class: 'btn btn bold green margin-top pull-right', title: "Abrir caja registradora" do %> Abrir caja <i class="fa fa-plus"></i><% end %> <br>
+                    <% end %>
+                    <% if can? :get_open_cash_registers, CashOut %>
+                      <%= link_to get_open_cash_registers_path, remote: true, data: { toggle: "modal", target: "#get_open_cash_register" }, class: "btn bold green pull-right", title: "Realizar corte de caja", style: "margin-top:10px"  do %> Realizar corte de caja <i class="fa fa-plus"></i>
                         <% end %>
-                      <% end %>
                     <% end %>
-                    <% if current_user.usertype == "A" %>
-                      <%= link_to opened_cash_registers_path, {:class=>"btn bold green pull-right"} do %> <i class="fa fa-search"></i>&nbsp Ver cajas abiertas <% end %>
+                    <% if can? :opened_cash_registers, CashOut %>
+                      <%= link_to opened_cash_registers_path, { class: "btn bold green pull-right" } do %> <i class="fa fa-search"></i>&nbsp Ver cajas abiertas <% end %>
                     <% end %>
                   </div>
                 </div>
@@ -65,7 +65,7 @@
                             <%= label_tag :pointsale, "pointsale", {:class=>"col-md-2 control-label"} do %> Punto de venta
                             <% end %>
                             <div class="col-md-3">
-                              <%= select_tag "pointsale", options_from_collection_for_select(Pointsale.vigentes, :id, :name, :selected => current_user.pointsale_id), :include_blank => "Todas", :disabled => (true unless current_user.usertype == 'A'),  class: "form-control select2 col-md-3" %>
+                              <%= select_tag "pointsale", options_from_collection_for_select(Pointsale.vigentes, :id, :name, :selected => current_user.pointsale_id), :include_blank => "Todas", :disabled => (true unless current_user.usertype == "A" || current_user.usertype == "SS"),  class: "form-control select2 col-md-3" %>
                             </div>
                             <%= label_tag :begin_date, "Fecha", {:class=>"col-md-1 control-label"} do %> Desde
                             <% end %>
@@ -100,7 +100,7 @@
                     <thead>
                       <tr>
                         <th>#</th>
-                        <% if current_user.usertype == "A" %>
+                        <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
                           <th>Punto de venta</th>
                         <% end %>
                         <th>Caja registradora</th>
@@ -117,7 +117,7 @@
                       <% @cash_outs.each_with_index do |cash_out, key| %>
                       <tr>
                         <td><%= cash_out.id %></td>
-                        <% if current_user.usertype == "A" %>
+                        <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
                           <td>
                           <%= OpenCashRegister.get_pointsale(cash_out.open_cash_register_id, "open_cash_register").name %>
                           </td>

+ 10 - 8
app/views/cash_outs/opened_cash_registers.html.erb

@@ -16,6 +16,8 @@
     <!-- BEGIN PAGE CONTENT BODY -->
     <div class="page-content">
       <div class="container-fluid">
+        <%= link_to cash_outs_path(:filter => @filter, :current_page => @current_page), {:class=>"btn blue-hoki pull-right margin-bottom-10"} do %> <i class="fa fa-angle-left "></i> Regresar
+        <% end %>
         <!-- BEGIN PAGE BREADCRUMBS -->
         <ul class="page-breadcrumb breadcrumb">
           <%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
@@ -41,14 +43,14 @@
                   <div class="caption">
                     <i class="fa fa-list "></i>
                     <span class="caption-subject bold uppercase">Lista de cajas abiertas</span>
-                  </div> 
+                  </div>
                 </div>
                 <div class="portlet-body">
                   <table class="table table-striped table-bordered table-hover tableadvanced" id="cash_outs_table">
                     <thead>
                       <tr>
                         <th>#</th>
-                        <th>Punto de venta</th> 
+                        <th>Punto de venta</th>
                         <th>Caja registradora</th>
                         <th>Ingresos</th>
                         <th>Egresos</th>
@@ -62,23 +64,23 @@
                         <tr>
                           <td><%= key + 1 %></td>
                           <td>
-                            <%= OpenCashRegister.get_pointsale(open_cash.id, "open_cash_register").name %> 
-                          </td> 
+                            <%= OpenCashRegister.get_pointsale(open_cash.id, "open_cash_register").name %>
+                          </td>
                           <td><%= open_cash.cash_register.name %> </td>
                           <td>
-                            <% amount_in =  CashRegistersMove.where(:open_cash_register => open_cash.id, :move_type =>  1).sum(:quantity) %> 
+                            <% amount_in =  CashRegistersMove.where(:open_cash_register => open_cash.id, :move_type =>  1).sum(:quantity) %>
                            <%= number_to_currency(amount_in, precision: 2) %>
                           </td>
                           <td>
                             <% amount_out = CashRegistersMove.where(:open_cash_register => open_cash.id, :move_type =>  0).sum(:quantity) %>
-                           <%= number_to_currency(amount_out, precision: 2) %>   
+                           <%= number_to_currency(amount_out, precision: 2) %>
                            </td>
                            <td>
-                             <%= number_to_currency((amount_in - amount_out), precision: 2) %>   
+                             <%= number_to_currency((amount_in - amount_out), precision: 2) %>
                            </td>
                           <td><%= open_cash.user.first_name %></td>
                           <td><%= l(open_cash.created_at, :format => '%I:%M %p') %></td>
-                        </tr>                      
+                        </tr>
                       <% end %>
                     </tbody>
                   </table>

+ 185 - 187
app/views/cash_outs/show.html.erb

@@ -18,12 +18,11 @@
 		<div class="page-content">
 			<div class="container-fluid">
 				<div class="pull-right margin-bottom-10 ">
-                    <a class="btn blue hidden-print" onclick="javascript:window.print();"> Imprimir
-                        <i class="fa fa-print"></i>
-                    </a>
-					<%= link_to  cash_outs_path(:filter => @filter, :current_page => @current_page), {:class=>"fr-space btn blue-hoki hidden-print"} do %>
-						<i class="fa fa-angle-left "></i>
-						Regresar
+          <a class="btn blue hidden-print" onclick="javascript:window.print();"> Imprimir
+	          <i class="fa fa-print"></i>
+          </a>
+					<%= link_to cash_outs_path(:filter => @filter, :current_page => @current_page), {:class=>"fr-space btn blue-hoki hidden-print"} do %>
+						<i class="fa fa-angle-left "></i> Regresar
 					<% end %>
 				</div>
 				<!-- BEGIN PAGE BREADCRUMBS -->
@@ -52,7 +51,7 @@
 												&nbsp&nbsp Fecha:</div>
 												<div class="col-md-6 value"> <%= l(@cash_out.created_at, :format => '%A, %d de %B de %Y') %>  </div>
 											</div>
-											<% if current_user.usertype == "A" %>
+											<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
 												<div class="row static-info">
 													<div class="col-md-6 name"><i class="fa fa-fw fa-cart-plus"></i> &nbsp Punto de venta:</div>
 													<div class="col-md-6 value"> <%= OpenCashRegister.get_pointsale(@cash_out.open_cash_register_id, "open_cash_register").name %>  </div>
@@ -81,33 +80,33 @@
 
 										<!-- para la vista de impresion -->
 										<ul class="list-unstyled visible-print">
-                                            <li>
-                                                <i class="fa fa-calendar-o"></i>&nbsp Fecha:
-                                                <strong><%= l(@cash_out.created_at, :format => '%A, %d de %B de %Y') %> </strong>
-                                            </li>
-                                            <% if current_user.usertype == "A" %>
-	                                            <li>
-	                                                <i class="fa fa-fw fa-cart-plus"></i>&nbsp Punto de venta:
-	                                                <strong><%= OpenCashRegister.get_pointsale(@cash_out.open_cash_register_id, "open_cash_register").name %></strong>
-	                                            </li>
-                                            <% end %>
-                                            <li>
-                                                <i class="fa fa-fw fa-cart-plus"></i>&nbsp Caja registradora:
-                                                <strong> <%= @cash_out.open_cash_register.cash_register.name %></strong>
-                                            </li>
-                                            <li>
-                                                <i class="fa fa-odnoklassniki"></i>&nbsp Realizó:
-                                                <strong> <%= @cash_out.user.first_name %> </strong>
-                                            </li>
-                                            <li>
-                                                <i class="fa fa-odnoklassniki"></i>&nbsp Recibió:
-                                                <strong> <%= @cash_out.received_by.first_name %> </strong>
-                                            </li>
-                                            <li>
-                                                <i class="fa fa-odnoklassniki"></i>&nbsp Observaciones:
-                                                <strong> <%= @cash_out.observations %> </strong>
-                                            </li>
-                                        </ul>
+                      <li>
+                        <i class="fa fa-calendar-o"></i>&nbsp Fecha:
+                        <strong><%= l(@cash_out.created_at, :format => '%A, %d de %B de %Y') %> </strong>
+                      </li>
+                      <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+                        <li>
+                          <i class="fa fa-fw fa-cart-plus"></i>&nbsp Punto de venta:
+                          <strong><%= OpenCashRegister.get_pointsale(@cash_out.open_cash_register_id, "open_cash_register").name %></strong>
+                        </li>
+                      <% end %>
+                      <li>
+                        <i class="fa fa-fw fa-cart-plus"></i>&nbsp Caja registradora:
+                        <strong> <%= @cash_out.open_cash_register.cash_register.name %></strong>
+                      </li>
+                      <li>
+                        <i class="fa fa-odnoklassniki"></i>&nbsp Realizó:
+                        <strong> <%= @cash_out.user.first_name %> </strong>
+                      </li>
+                      <li>
+                        <i class="fa fa-odnoklassniki"></i>&nbsp Recibió:
+                        <strong> <%= @cash_out.received_by.first_name %> </strong>
+                      </li>
+                      <li>
+                        <i class="fa fa-odnoklassniki"></i>&nbsp Observaciones:
+                        <strong> <%= @cash_out.observations %> </strong>
+                      </li>
+                  	</ul>
 									</div>
 								</div>
 							</div>
@@ -120,106 +119,105 @@
 										<div class="">
 											<div class="row">
 												<div class="col-md-4">
-												    <div class="hidden-print" style="padding-left: 0px">
-												      <ul class="list-group">
-												        <li class="list-group-item list-group-item-default"> Total de ventas
-												        <span class="pull-right label label-warning"><%= number_to_currency(@sales_total, precision: 2) %></span>
-												        </li>
-												      </ul>
-												    </div>
+											    <div class="hidden-print" style="padding-left: 0px">
+											      <ul class="list-group">
+											        <li class="list-group-item list-group-item-default"> Total de ventas
+											        <span class="pull-right label label-warning"><%= number_to_currency(@sales_total, precision: 2) %></span>
+											        </li>
+											      </ul>
+											    </div>
 												</div>
 												<div class="col-md-4">
-												    <div class="hidden-print" style="padding-left: 0px">
-												      <ul class="list-group">
-												        <li class="list-group-item list-group-item-default"> Total de egresos
-												        <span class="pull-right label label-warning"><%= number_to_currency(@expenses_total, precision: 2) %></span>
-												        </li>
-												      </ul>
-												    </div>
+											    <div class="hidden-print" style="padding-left: 0px">
+											      <ul class="list-group">
+											        <li class="list-group-item list-group-item-default"> Total de egresos
+											        <span class="pull-right label label-warning"><%= number_to_currency(@expenses_total, precision: 2) %></span>
+											        </li>
+											      </ul>
+											    </div>
 												</div>
 
 												<div class="col-md-4">
-												    <div class="hidden-print" style="padding-left: 0px">
-												      <ul class="list-group">
-												        <li class="list-group-item list-group-item-default"> Efectivo inicial
-												        <span class="pull-right label label-warning"><%= number_to_currency(@cash_out.open_cash_register.initial_cash, precision: 2) %></span>
-												        </li>
-												      </ul>
-												    </div>
+											    <div class="hidden-print" style="padding-left: 0px">
+											      <ul class="list-group">
+											        <li class="list-group-item list-group-item-default"> Efectivo inicial
+											        <span class="pull-right label label-warning"><%= number_to_currency(@cash_out.open_cash_register.initial_cash, precision: 2) %></span>
+											        </li>
+											      </ul>
+											    </div>
 												</div>
 
 												<div class="col-md-4">
-												    <div class="hidden-print" style="padding-left: 0px">
-												      <ul class="list-group">
-												        <li class="list-group-item list-group-item-default"> Retiro
-												        <span class="pull-right label label-warning"><%= number_to_currency(@cash_out.received_cash, precision: 2) %></span>
-												        </li>
-												      </ul>
-												    </div>
+											    <div class="hidden-print" style="padding-left: 0px">
+											      <ul class="list-group">
+											        <li class="list-group-item list-group-item-default"> Retiro
+											        <span class="pull-right label label-warning"><%= number_to_currency(@cash_out.received_cash, precision: 2) %></span>
+											        </li>
+											      </ul>
+											    </div>
 												</div>
 
 												<div class="col-md-4">
-												    <div class="hidden-print" style="padding-left: 0px">
-												      <ul class="list-group">
-												        <li class="list-group-item list-group-item-default"> Fondo
-												        <span class="pull-right label label-warning"><%= number_to_currency(@cash_out.cash_fund, precision: 2) %></span>
-												        </li>
-												      </ul>
-												    </div>
+											    <div class="hidden-print" style="padding-left: 0px">
+											      <ul class="list-group">
+											        <li class="list-group-item list-group-item-default"> Fondo
+											        <span class="pull-right label label-warning"><%= number_to_currency(@cash_out.cash_fund, precision: 2) %></span>
+											        </li>
+											      </ul>
+											    </div>
 												</div>
 											</div>
 											<!-- saldo inicial de la caja para el view-->
 
 											<!-- saldo inicial de la caja para el print view -->
 											<ul class="list-unstyled visible-print">
-	                                            <li>
-	                                                <i class="fa fa-money"></i>&nbsp Total de ventas:
-	                                                <strong><%= number_to_currency(@sales_total, precision: 2) %> </strong>
-	                                            </li>
-	                                            <li>
-	                                                <i class="fa fa-money"></i>&nbsp Total de egresos:
-	                                                <strong><%= number_to_currency(@expenses_total, precision: 2) %> </strong>
-	                                            </li>
-	                                            <li>
-	                                                <i class="fa fa-money"></i>&nbsp Efectivo inicial:
-	                                                <strong><%= number_to_currency(@cash_out.open_cash_register.initial_cash, precision: 2) %> </strong>
-	                                            </li>
-	                                            <li>
-	                                                <i class="fa fa-money"></i>&nbsp Retiro de efectivo:
-	                                                <strong><%= number_to_currency(@cash_out.received_cash, precision: 2) %> </strong>
-	                                            </li>
-	                                            <li>
-	                                                <i class="fa fa-money"></i>&nbsp Fondo de caja:
-	                                                <strong><%= number_to_currency(@cash_out.cash_fund, precision: 2) %> </strong>
-	                                            </li>
-
+                        <li>
+                          <i class="fa fa-money"></i>&nbsp Total de ventas:
+                          <strong><%= number_to_currency(@sales_total, precision: 2) %> </strong>
+                        </li>
+                        <li>
+                          <i class="fa fa-money"></i>&nbsp Total de egresos:
+                          <strong><%= number_to_currency(@expenses_total, precision: 2) %> </strong>
+                        </li>
+                        <li>
+                          <i class="fa fa-money"></i>&nbsp Efectivo inicial:
+                          <strong><%= number_to_currency(@cash_out.open_cash_register.initial_cash, precision: 2) %> </strong>
+                        </li>
+                        <li>
+                          <i class="fa fa-money"></i>&nbsp Retiro de efectivo:
+                          <strong><%= number_to_currency(@cash_out.received_cash, precision: 2) %> </strong>
+                        </li>
+                        <li>
+                          <i class="fa fa-money"></i>&nbsp Fondo de caja:
+                          <strong><%= number_to_currency(@cash_out.cash_fund, precision: 2) %> </strong>
+                        </li>
 											</ul>
-									        <table class="table table-striped table-hover">
-									            <thead>
-									                <tr class="uppercase">
-									                    <th> # </th>
-									                    <th> Método de pago </th>
-									                    <th> total de ingresos </th>
-									                    <th> total de egresos </th>
-									                    <th> Total </th>
-									                </tr>
-									            </thead>
-									            <tbody>
-									              <% @cash_out.cash_out_details.each_with_index do |detail, key| %>
-									                <tr>
-									                  <td> <%= key +1 %> </td>
-									                  <td> <%= detail.payment_method.method %> </td>
-									                  <td> <%= number_to_currency(detail.incoming, precision: 2) %> </td>
-									                  <td> <%= number_to_currency(detail.outgoing, precision: 2) %> </td>
-									                  <td>
-									                    <%= number_to_currency(detail.total, precision: 2) %>
-									                  </td>
-									                </tr>
-									              <% end %>
-									            </tbody>
-					                    	</table>
+							        <table class="table table-striped table-hover">
+						            <thead>
+					                <tr class="uppercase">
+				                    <th> # </th>
+				                    <th> Método de pago </th>
+				                    <th> total de ingresos </th>
+				                    <th> total de egresos </th>
+				                    <th> Total </th>
+					                </tr>
+						            </thead>
+						            <tbody>
+						              <% @cash_out.cash_out_details.each_with_index do |detail, key| %>
+						                <tr>
+						                  <td> <%= key +1 %> </td>
+						                  <td> <%= detail.payment_method.method %> </td>
+						                  <td> <%= number_to_currency(detail.incoming, precision: 2) %> </td>
+						                  <td> <%= number_to_currency(detail.outgoing, precision: 2) %> </td>
+						                  <td>
+						                    <%= number_to_currency(detail.total, precision: 2) %>
+						                  </td>
+						                </tr>
+						              <% end %>
+						            </tbody>
+                    	</table>
 										</div>
-			                    	</div>
+                	</div>
 								</div>
 							</div>
 							<div class="col-md-12 col-sm-12">
@@ -230,41 +228,41 @@
 									<div class="portlet-body">
 										<table class="table table-striped table-hover">
 											<thead>
-										        <tr>
-										          <th>#</th>
-										          <th>Folio</th>
-										          <th>Caja registradora</th>
-										          <th>Método de pago</th>
-										          <th>Cantidad</th>
-										          <th>Concepto</th>
-										          <th>Hora</th>
-										        </tr>
+								        <tr>
+								          <th>#</th>
+								          <th>Folio</th>
+								          <th>Caja registradora</th>
+								          <th>Método de pago</th>
+								          <th>Cantidad</th>
+								          <th>Concepto</th>
+								          <th>Hora</th>
+								        </tr>
 											</thead>
 											<tbody>
-										        <% @incomings.each_with_index do |move, key| %>
-										        <tr>
-										          <td><%= key + 1 %></td>
-										          <td>
-										            <% case move.concept %>
-          												<% when "sale",  "reserved_payment", "reserved_first_payment", "reserved_last_payment", "products_return" %>
-										                <%= move.sale.sale_code %>
-										              <% when "purchase"%>
-										                <%= move.purchase.purchase_code %>
-										              <% when "expense"%>
-										                <%= move.expense.expense_code %>
-										              <% when "credit_payment"%>
-										                <%= move.credit_payment.id %>
-										            <% end %>
-										          </td>
-										          <td><%= move.open_cash_register.cash_register.name%></td>
-										          <td><%= move.payment_method.method %></td>
-										          <td><%= number_to_currency(move.quantity, precision: 2) %></td>
-										          <td>
-                                  <%= cash_move_type(move) %>
-								           		 </td>
-										          <td><%= l(move.created_at, :format => '%I:%M %p') %> </td>
-										        </tr>
-										        <% end %>
+								        <% @incomings.each_with_index do |move, key| %>
+									        <tr>
+									          <td><%= key + 1 %></td>
+									          <td>
+									            <% case move.concept %>
+        												<% when "sale",  "reserved_payment", "reserved_first_payment", "reserved_last_payment", "products_return" %>
+									                <%= move.sale.sale_code %>
+									              <% when "purchase"%>
+									                <%= move.purchase.purchase_code %>
+									              <% when "expense"%>
+									                <%= move.expense.expense_code %>
+									              <% when "credit_payment"%>
+									                <%= move.credit_payment.id %>
+									            <% end %>
+									          </td>
+									          <td><%= move.open_cash_register.cash_register.name%></td>
+									          <td><%= move.payment_method.method %></td>
+									          <td><%= number_to_currency(move.quantity, precision: 2) %></td>
+									          <td>
+                              <%= cash_move_type(move) %>
+							           		</td>
+									          <td><%= l(move.created_at, :format => '%I:%M %p') %> </td>
+									        </tr>
+								        <% end %>
 											</tbody>
 										</table>
 									</div>
@@ -278,47 +276,47 @@
 									<div class="portlet-body">
 										<table class="table table-striped table-hover">
 											<thead>
-										        <tr>
-										          <th>#</th>
-										          <th>Folio</th>
-										          <th>Caja registradora</th>
-										          <th>Método de pago</th>
-										          <th>Cantidad</th>
-										          <th>Concepto</th>
-										          <th>Hora</th>
-										        </tr>
+								        <tr>
+								          <th>#</th>
+								          <th>Folio</th>
+								          <th>Caja registradora</th>
+								          <th>Método de pago</th>
+								          <th>Cantidad</th>
+								          <th>Concepto</th>
+								          <th>Hora</th>
+								        </tr>
 											</thead>
 											<tbody>
-										        <% @outgoings.each_with_index do |move, key| %>
-										        <tr>
-										          <td><%= key + 1 %></td>
-										          <td>
-										            <% case move.concept %>
-										              <% when "sale",  "reserved_payment",  "credit_payment" %>
-										                <%= move.sale.sale_code %>
-										              <% when "purchase"%>
-										                <%= move.purchase.purchase_code %>
-										              <% when "expense"%>
-										                <%= move.expense.expense_code %>
-										            <% end %>
-										          </td>
-										          <td><%= move.open_cash_register.cash_register.name%></td>
-										          <td><%= move.payment_method.method %></td>
-										          <td><%= number_to_currency(move.quantity, precision: 2) %></td>
-										          <td>
-						                          	<% case move.concept %>
-						                          	<% when "sale"%>
-						                            	Venta cancelada
-						                          	<% when "purchase"%>
-						                            	Compra
-						                          	<% when "expense"%>
-										                <strong> <%= move.expense.expensesconcept.name %></strong> <br>
-										                <%= move.expense.observations %>
-							                          <% end %>
-								           		 </td>
-										          <td><%= l(move.created_at, :format => '%I:%M %p') %> </td>
-										        </tr>
-										        <% end %>
+								        <% @outgoings.each_with_index do |move, key| %>
+									        <tr>
+									          <td><%= key + 1 %></td>
+									          <td>
+									            <% case move.concept %>
+									              <% when "sale",  "reserved_payment",  "credit_payment" %>
+									                <%= move.sale.sale_code %>
+									              <% when "purchase"%>
+									                <%= move.purchase.purchase_code %>
+									              <% when "expense"%>
+									                <%= move.expense.expense_code %>
+									            <% end %>
+									          </td>
+									          <td><%= move.open_cash_register.cash_register.name%></td>
+									          <td><%= move.payment_method.method %></td>
+									          <td><%= number_to_currency(move.quantity, precision: 2) %></td>
+									          <td>
+	                          	<% case move.concept %>
+	                          	<% when "sale" %>
+    	                        	Venta cancelada
+	                          	<% when "purchase" %>
+	                            	Compra
+	                          	<% when "expense" %>
+								                <strong> <%= move.expense.expensesconcept.name %></strong> <br>
+								                <%= move.expense.observations %>
+		                          <% end %>
+							           		</td>
+									          <td><%= l(move.created_at, :format => '%I:%M %p') %> </td>
+									        </tr>
+								        <% end %>
 											</tbody>
 										</table>
 									</div>

+ 35 - 57
app/views/cash_registers/_form.html.erb

@@ -1,57 +1,35 @@
-											<%= form_for(@cash_register, :html => {:class=>"form-horizontal"}) do |f| %>
-											<div class="portlet-body form">
-												<% if @cash_register.errors.any? %>
-												<div class="alert alert-danger">
-													<strong>Tiene <%= pluralize(@cash_register.errors.count, "error") %> no se puede guardar la caja registradora</strong><br>
-												</div>
-												<% end %>
-												<div class="form-body">
-													<div class="form-group">
-                                                        <%= f.label :name, "Nombre de la caja", {:class=>"col-md-3 control-label"} do %> Nombre de la caja
-															<span class="required">*</span>
-														<% end %>
-														<div class="col-md-9">
-															<%= f.text_field :name, {:class=>"form-control"} %>
-														</div>
-													</div>
-													<div class="form-group">
-                                                        <%= f.label :decription, "Descripción", {:class=>"col-md-3 control-label"} %>
-														<div class="col-md-9">
-                                                            <%= f.text_field :description, {:class=>"form-control"} %>
-														</div>
-													</div>                                                 
-													<% if @cash_register.persisted? %>
-													<!-- <div class="form-group">
-														<%= f.label :status, {:class=>"col-md-3 control-label"} %>
-														<div class="col-md-9">
-															<%= f.check_box(:status,   
-																{
-																	class: "make-switch",
-																	data: {
-																		on_color: "success",
-																		off_color: "danger",
-																		on_text: "Activo", 
-																		off_text: "Inactivo"
-																	}
-																},
-																"active", "inactive"  
-															) %>
-														</div>
-													</div> -->
-													<% end %>
-                                            </div>
-												<div class="form-actions">
-													<div class="row">
-														<div class="col-md-offset-3 col-md-9">
-															<%= f.submit 'Guardar', {:class=>"btn green"} %>
-															<%= link_to 'Cancelar', cash_registers_path, {:class=>"btn default"} %>
-														</div>
-													</div>
-												</div>
-											</div>
-											<% end %>
-											<script type="text/javascript">
-												$(document).ready(function() {
-													App.init();
-												});
-											</script>
+<%= form_for(@cash_register, remote: true, html: { class: "form-horizontal" }) do |f| %>
+  <div class="portlet-body form">
+    <div class="row col-md-12">
+      <div class="alert alert-danger hidden" id="cash_register_errors"></div>
+    </div>
+    <div class="form-body">
+      <div class="form-group">
+        <%= f.label :name, "Nombre de la caja", { class: "col-md-3 control-label" } do %> Nombre de la caja
+          <span class="required">*</span>
+        <% end %>
+        <div class="col-md-8">
+          <%= f.text_field :name, { class: "form-control first_input" } %>
+        </div>
+      </div>
+      <div class="form-group">
+        <%= f.label :decription, "Descripción", { class: "col-md-3 control-label" } %>
+        <div class="col-md-8">
+          <%= f.text_area :description, { class: "form-control", rows: 4 } %>
+        </div>
+      </div>
+    </div>
+    <div class="form-actions">
+      <div class="row">
+        <div class="col-md-offset-3 col-md-9">
+          <%= f.submit 'Guardar', { class: "btn green" } %>
+        </div>
+      </div>
+    </div>
+  </div>
+<% end %>
+<script type="text/javascript">
+  $(document).ready(function() {
+    App.init();
+  });
+</script>

+ 11 - 0
app/views/cash_registers/create.js.erb

@@ -0,0 +1,11 @@
+$("#cash_register_errors").html("");
+<% if @cash_register.errors.any? %>
+  $('#cash_register_errors').removeClass('hidden');
+  <% @cash_register.errors.values.each do |message| %>
+    $("#cash_register_errors").append($("<li />").html("<%= message.first.to_s %>"));
+  <% end %>
+<% else %>
+  $('#dialog').modal('toggle');
+  window.location = "<%= cash_registers_path %>";
+  $("#notice").html("<%= flash[:notice] %>");
+<% end %>

+ 0 - 52
app/views/cash_registers/edit.html.erb

@@ -1,52 +0,0 @@
-
-	<!-- BEGIN CONTAINER -->
-	<div class="page-container">
-		<!-- BEGIN CONTENT -->
-		<div class="page-content-wrapper">
-			<!-- BEGIN CONTENT BODY -->
-			<!-- BEGIN PAGE HEAD-->
-			<div class="page-head">
-				<div class="container-fluid">
-					<!-- BEGIN PAGE TITLE -->
-					<div class="page-title">
-						<h1>Caja registradora </h1>
-					</div>
-					<!-- END PAGE TITLE -->
-				</div>
-			</div>
-			<!-- END PAGE HEAD-->
-			<!-- BEGIN PAGE CONTENT BODY -->
-			<div class="page-content">
-				<div class="container-fluid">
-					<%= link_to cash_registers_path, {:class=>"btn blue-hoki pull-right margin-bottom-10"} do %>  <i class="fa fa-angle-left "></i> Regresar
-					<% end %>
-					<!-- BEGIN PAGE BREADCRUMBS -->
-					<ul class="page-breadcrumb breadcrumb">
-						<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
-					</ul>
-					<!-- END PAGE BREADCRUMBS -->
-					<!-- BEGIN PAGE CONTENT INNER -->
-					<div class="page-content-inner">
-						<div class="row ">
-							<div class="col-md-12">
-								<div class="portlet light">
-									<div class="portlet-title">
-										<div class="caption">
-											<i class="fa fa-edit font-blue-sharp"></i>
-											<span class="caption-subject font-blue-sharp bold uppercase">Editar caja registradora</span>
-										</div>
-									</div>
-									<%= render 'form' %>
-								</div>
-							</div>
-						</div> 
-					</div>
-					<!-- END PAGE CONTENT INNER -->
-				</div>
-			</div>
-			<!-- END PAGE CONTENT BODY -->
-			<!-- END CONTENT BODY -->
-		</div>
-		<!-- END CONTENT -->
-	</div>
-	<!-- END CONTAINER -->

+ 14 - 0
app/views/cash_registers/edit.js.erb

@@ -0,0 +1,14 @@
+$('#dialog h3.modal-title').html("Editar caja registradora");
+$('#dialog').removeClass('modal-lg');
+$('.modal-footer').remove();
+$('.modal-body').html(""); //limpiar el modal antes; la siguiente linea es por si se abrio previamente el detalle de venta
+$('.modal-dialog').removeClass('modal-lg');
+// Rend$( ".selector" ).dialog({ closeOnEscape: false });er the edit form
+$('.modal-body').html('<%= j render("form") %>');
+// Show the dynamic dialog
+$('#dialog').modal("show");
+
+// Set focus to the first element
+$('#dialog').on('shown.bs.modal', function () {
+  $('.first_input').focus();
+});

+ 30 - 26
app/views/cash_registers/index.html.erb

@@ -25,7 +25,7 @@
 						<!-- BEGIN PAGE CONTENT INNER -->
 						<div class="page-content-inner">
 							<div id="notice">
-								<% if success %> 
+								<% if success %>
 								<div class="alert alert-success">
 									<p><%= success %></p>
 								</div>
@@ -45,8 +45,7 @@
 											</div>
 											<div class="actions">
 												<% if can? :create, CashRegister %>
-												<%= link_to new_cash_register_path, {:class=>"btn bold green pull-right"} do %> Nueva Caja registradora <i class="fa fa-plus"></i>
-												<% end %>
+													<%= link_to new_cash_register_path, remote: true, class: "btn bold green pull-right" do %> Nueva Caja registradora <i class="fa fa-plus"></i><% end %>
 												<% end %>
 											</div>
 										</div>
@@ -57,10 +56,12 @@
 														<th>#</th>
 														<th>Nombre</th>
 														<th>Descripción</th>
-														<% if current_user.usertype == "A" %><th>Punto de venta</th> <% end %>
+														<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+															<th>Punto de venta</th>
+														<% end %>
 														<th>Status</th>
 														<% if can? :manage, CashRegister %>
-														<th>Acciones</th> 
+															<th>Acciones</th>
 														<% end %>
 													</tr>
 												</thead>
@@ -70,31 +71,34 @@
 														<td><%= key + 1 %></td>
 														<td><%= cash_register.name %></td>
 														<td><%= cash_register.description %></td>
-														<% if current_user.usertype == "A" %><td><%= cash_register.pointsale.name %> </td> <% end %>
-														<td class="text-center"><% if cash_register.status == "active" %>
+														<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+															<td><%= cash_register.pointsale.name %> </td>
+														<% end %>
+														<td class="text-center">
+															<% if cash_register.active? %>
 																<i class="fa fa-check font-green"></i>
-																<% else %>
+															<% else %>
 																<i class="fa fa-times font-red"></i>
-																<% end %>
-														</td>
-														<% if can? :manage, CashRegister %>
-														<td class="text-center">
-															<%= link_to edit_cash_register_path(cash_register), {:class=>"btn btn-icon-only btn-primary", :title=>"Editar caja registradora"} do %> <i class="fa fa-edit"></i>
 															<% end %>
-															<% if !cash_register.main? && cash_register.open_cash_registers.where("status = 0").count == 0 %>
-																<% if cash_register.active? %>
-									                              <%= link_to cash_register_update_status_path(cash_register), :class=>"btn btn-icon-only default", :title=>"Desactivar caja registadora", data: { confirm: '¿Esta seguro de desactivar la caja registadora?', method: 'post'}  do %>
-									                                <i class="fa fa-toggle-off"></i>
-									                              <% end %>
-									                            <% elsif cash_register.inactive? %>
-									                              <%= link_to cash_register_update_status_path(cash_register), :class=>"btn btn-icon-only green-jungle", :title=>"Activar caja registadora", data: { confirm: '¿Esta seguro de activar la caja registadora?', method: 'post'}  do %>
-									                                <i class="fa fa-toggle-on"></i>
-									                              <% end %>
-									                            <% end %>
-																<%= link_to cash_register_path(cash_register), method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Eliminar caja registradora", data: { confirm: '¿Esta seguro de eliminar la caja registradora?'}   do %>  <i class="fa fa-trash-o"></i>
-																<% end %>      
-															<% end %>                                     
 														</td>
+														<% if can? :manage, CashRegister %>
+															<td class="text-center">
+																<%= link_to edit_cash_register_path(cash_register), remote: true, class: "btn btn-icon-only btn-primary", title: "Editar caja registradora" do %> <i class="fa fa-edit"></i>
+																<% end %>
+																<% if !cash_register.main? && cash_register.open_cash_registers.abiertas.count == 0 %>
+																	<% if cash_register.active? %>
+			                              <%= link_to cash_register_update_status_path(cash_register), class: "btn btn-icon-only default", title: "Desactivar caja registadora", data: { confirm: '¿Está seguro de desactivar la caja registadora?', method: 'post' } do %>
+			                                <i class="fa fa-toggle-off"></i>
+			                              <% end %>
+			                            <% elsif cash_register.inactive? %>
+			                              <%= link_to cash_register_update_status_path(cash_register), class: "btn btn-icon-only green-jungle", title: "Activar caja registadora", data: { confirm: '¿Está seguro de activar la caja registadora?', method: 'post' } do %>
+			                                <i class="fa fa-toggle-on"></i>
+			                              <% end %>
+			                            <% end %>
+																	<%= link_to cash_register_path(cash_register), method: :delete, class: "btn btn-icon-only btn-danger", title: "Eliminar caja registradora", data: { confirm: '¿Está seguro de eliminar la caja registradora?' } do %> <i class="fa fa-trash-o"></i>
+																	<% end %>
+																<% end %>
+															</td>
 														<% end %>
 													</tr>
 												<% end %>

+ 0 - 52
app/views/cash_registers/new.html.erb

@@ -1,52 +0,0 @@
-	<!-- BEGIN CONTAINER -->
-	<div class="page-container">
-		<!-- BEGIN CONTENT -->
-		<div class="page-content-wrapper">
-			<!-- BEGIN CONTENT BODY -->
-			<!-- BEGIN PAGE HEAD-->
-			<div class="page-head">
-				<div class="container-fluid">
-					<!-- BEGIN PAGE TITLE -->
-					<div class="page-title">
-						<h1>Caja registradora</h1>
-					</div>
-					<!-- END PAGE TITLE -->
-				</div>
-			</div>
-			<!-- END PAGE HEAD-->
-			<!-- BEGIN PAGE CONTENT BODY -->
-			<div class="page-content">
-				<div class="container-fluid">
-					<%= link_to  cash_registers_path, {:class=>"btn blue-hoki pull-right margin-bottom-10"} do %>  <i class="fa fa-angle-left "></i> Regresar
-					<% end %>
-					<!-- BEGIN PAGE BREADCRUMBS -->
-					<ul class="page-breadcrumb breadcrumb">
-						<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
-					</ul>
-					<!-- END PAGE BREADCRUMBS -->
-					<!-- BEGIN PAGE CONTENT INNER -->
-					<div class="page-content-inner">
-						<div id="notice"><%= notice %></div>
-						<div class="row ">
-							<div class="col-md-12">
-								<div class="portlet light">
-									<div class="portlet-title">
-										<div class="caption">
-											<i class="fa fa-plus font-green"></i>
-											<span class="caption-subject font-green bold uppercase">Nueva caja registradora</span>
-										</div>
-									</div>
-									<%= render 'form' %>
-								</div>
-							</div>
-						</div>                       
-					</div>
-					<!-- END PAGE CONTENT INNER -->
-				</div>
-			</div>
-			<!-- END PAGE CONTENT BODY -->
-			<!-- END CONTENT BODY -->
-		</div>
-		<!-- END CONTENT -->
-	</div>
-	<!-- END CONTAINER -->

+ 14 - 0
app/views/cash_registers/new.js.erb

@@ -0,0 +1,14 @@
+$('#dialog h3.modal-title').html("Nueva caja registradora");
+$('#dialog').removeClass('modal-lg');
+$('.modal-footer').remove();
+$('.modal-body').html(""); //limpiar el modal antes; la siguiente linea es por si se abrio previamente el detalle de venta
+$('.modal-dialog').removeClass('modal-lg');
+// Rend$( ".selector" ).dialog({ closeOnEscape: false });er the edit form
+$('.modal-body').html('<%= j render("form") %>');
+// Show the dynamic dialog
+$('#dialog').modal("show");
+
+// Set focus to the first element
+$('#dialog').on('shown.bs.modal', function () {
+  $('.first_input').focus();
+});

+ 11 - 0
app/views/cash_registers/update.js.erb

@@ -0,0 +1,11 @@
+$("#cash_register_errors").html("");
+<% if @cash_register.errors.any? %>
+  $('#cash_register_errors').removeClass('hidden');
+  <% @cash_register.errors.values.each do |message| %>
+    $("#cash_register_errors").append($("<li />").html("<%= message.first.to_s %>"));
+  <% end %>
+<% else %>
+  $('#dialog').modal('toggle');
+  window.location = "<%= cash_registers_path %>";
+  $("#notice").html("<%= flash[:notice] %>");
+<% end %>

+ 128 - 131
app/views/commissions/_sellers_for_commissions.html.erb

@@ -1,148 +1,145 @@
 <div class="form-horizontal">
-    <div class="portlet-body form">
-        <div class="form-body">
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                       <%= label_tag :pointsale_id,  {:class=>"col-md-3 control-label"} do %>Punto de venta <span class="required">*</span> <% end %>
-                        <div class="col-md-8" style="padding-right:0px">
-                            <% if current_user.usertype == 'A' %>
-                              <%= select_tag :pointsale_id, options_from_collection_for_select(Pointsale.activos, :id, :name), :include_blank => "Seleccione punto de venta",  class: "form-control select2" %>
-                            <% else %>
-                                <%= text_field_tag 'pointsale', current_user.pointsale.name, :class => 'form-control', :disabled => true %>
-                                <%= hidden_field_tag 'pointsale_id', current_user.pointsale_id %>
-                            <% end %>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                      <%= label_tag :initial_date, "Fecha", {:class=>"col-md-2 control-label"} do %>Desde <span class="required">*</span> <% end %>
-                      <div class="col-md-3" style="padding-left:0px;padding-right:0px;margin-left:15px">
-                          <div class='input-group date' id='initial_date'>
-                              <input id="start" type='text' class="form-control"/>
-                              <span class="input-group-addon">
-                                  <span class="glyphicon glyphicon-calendar"></span>
-                              </span>
-                          </div>
-                      </div>
-                      <%= label_tag :final_date, "Fecha", {:class=>"col-md-2 control-label"} do %>Hasta <span class="required">*</span> <% end %>
-                      <div class="col-md-3" style="padding-left:0px;padding-right:0px;">
-                          <div class='input-group date' id='final_date'>
-                              <input id="end" type='text' class="form-control"/>
-                              <span class="input-group-addon">
-                                  <span class="glyphicon glyphicon-calendar"></span>
-                              </span>
-                          </div>
-                      </div>
-                      <button class="btn btn-icon-only blue" style="margin-left:25px" onclick="getSellersByDates()">
-                        <i class="fa fa-search"></i>
-                      </button>
-                    </div>
-                    <div class="form-group">
-                        <div class="form-group" id="sellers_div">
-                            <%= label_tag :sellers_ids, "Vendores", {:class=>"col-md-3 control-label"} do %>Vendedores <span class="required">*</span> <% end %>
-                            <div class="col-md-9" style="padding-left:20px">
-                                <div class="row" style="margin-bottom:10px">
-                                    <div class="col-md-12">
-                                        <button type="button" class="btn btn-default" id='select-all'><i class="fa fa fa-square-o"></i> Seleccionar todo</button>
-                                        <button style="margin-left:55px" type="button" class="btn btn-default" id='deselect-all'><i class="fa fa-square-o"></i> Deseleccionar todo</button>
-                                    </div>
-                                </div>
-                                <%= select_tag :sellers_ids, nil, multiple: true, class: 'multi-select' %>
-                            </div>
-                        </div>
-                    </div>
+  <div class="portlet-body form">
+    <div class="form-body">
+      <div class="row">
+        <div class="col-md-12">
+          <div class="form-group">
+            <%= label_tag :pointsale_id,  {:class=>"col-md-3 control-label"} do %>Punto de venta <span class="required">*</span> <% end %>
+            <div class="col-md-8" style="padding-right:0px">
+              <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+                <%= select_tag :pointsale_id, options_from_collection_for_select(Pointsale.activos, :id, :name), :include_blank => "Seleccione punto de venta",  class: "form-control select2" %>
+              <% else %>
+                <%= text_field_tag 'pointsale', current_user.pointsale.name, :class => 'form-control', :disabled => true %>
+                <%= hidden_field_tag 'pointsale_id', current_user.pointsale_id %>
+              <% end %>
+            </div>
+          </div>
+          <div class="form-group">
+            <%= label_tag :initial_date, "Fecha", {:class=>"col-md-2 control-label"} do %>Desde <span class="required">*</span> <% end %>
+            <div class="col-md-3" style="padding-left:0px;padding-right:0px;margin-left:15px">
+              <div class='input-group date' id='initial_date'>
+                <input id="start" type='text' class="form-control"/>
+                <span class="input-group-addon">
+                  <span class="glyphicon glyphicon-calendar"></span>
+                </span>
+              </div>
+            </div>
+            <%= label_tag :final_date, "Fecha", {:class=>"col-md-2 control-label"} do %>Hasta <span class="required">*</span> <% end %>
+            <div class="col-md-3" style="padding-left:0px;padding-right:0px;">
+              <div class='input-group date' id='final_date'>
+                <input id="end" type='text' class="form-control"/>
+                <span class="input-group-addon">
+                  <span class="glyphicon glyphicon-calendar"></span>
+                </span>
+              </div>
+            </div>
+            <button class="btn btn-icon-only blue" style="margin-left:25px" onclick="getSellersByDates()">
+              <i class="fa fa-search"></i>
+            </button>
+          </div>
+          <div class="form-group">
+            <div class="form-group" id="sellers_div">
+              <%= label_tag :sellers_ids, "Vendores", {:class=>"col-md-3 control-label"} do %>Vendedores <span class="required">*</span> <% end %>
+              <div class="col-md-9" style="padding-left:20px">
+                <div class="row" style="margin-bottom:10px">
+                  <div class="col-md-12">
+                    <button type="button" class="btn btn-default" id='select-all'><i class="fa fa fa-square-o"></i> Seleccionar todo</button>
+                    <button style="margin-left:55px" type="button" class="btn btn-default" id='deselect-all'><i class="fa fa-square-o"></i> Deseleccionar todo</button>
+                  </div>
                 </div>
+                <%= select_tag :sellers_ids, nil, multiple: true, class: 'multi-select' %>
+              </div>
             </div>
+          </div>
         </div>
+      </div>
     </div>
-    <div class="form-actions">
-        <h4 class="form-section"> </h4>
-        <div class="row">
-            <div class="col-md-12">
-                <button type="button" class="btn green" disabled=​"disabled" onclick="generateCommissions()" id="generate_button">Generar comisiones</button>
-                <button type="button" class="btn default" onclick="cerrarDialog()">Cerrar</button>
-            </div>
-        </div>
+  </div>
+  <div class="form-actions">
+    <h4 class="form-section"> </h4>
+    <div class="row">
+      <div class="col-md-12">
+        <button type="button" class="btn green" disabled=​"disabled" onclick="generateCommissions()" id="generate_button">Generar comisiones</button>
+        <button type="button" class="btn default" onclick="cerrarDialog()">Cerrar</button>
+      </div>
     </div>
+  </div>
 </div>
 <script>
-    function cerrarDialog() {
-        $('#dialog').modal('toggle');
-    }
+  function cerrarDialog() {
+    $('#dialog').modal('toggle');
+  }
 
-    $('#initial_date').datetimepicker({
-        icons: {
-            date: "fa fa-calendar"
-        },
-        format: "DD/MM/YYYY"
-    });
+  $('#initial_date').datetimepicker({
+    icons: {
+      date: "fa fa-calendar"
+    },
+    format: "DD/MM/YYYY"
+  });
 
-    $('#final_date').datetimepicker({
-        icons: {
-            date: "fa fa-calendar"
-        },
-        format: "DD/MM/YYYY"
-    });
+  $('#final_date').datetimepicker({
+    icons: {
+      date: "fa fa-calendar"
+    },
+    format: "DD/MM/YYYY"
+  });
 
-    function getSellersByDates() {
-        if ($("#initial_date").data("date") && $("#final_date").data("date") && $('#pointsale_id').val()) {
+  function getSellersByDates() {
+    if ($("#initial_date").data("date") && $("#final_date").data("date") && $('#pointsale_id').val()) {
+      var initial_date = moment($("#initial_date").data("date"), "DD-MM-YYYY").startOf('day').format('YYYY-MM-DD HH:mm:ss');
+      var final_date = moment($("#final_date").data("date"), "DD-MM-YYYY").endOf('day').format('YYYY-MM-DD HH:mm:ss');
+      var pointsale_id = $('#pointsale_id').val();
+      App.blockUI({
+        target: $("#sellers_div"),
+        animate: true
+      });
 
-            var initial_date = moment($("#initial_date").data("date"), "DD-MM-YYYY").startOf('day').format('YYYY-MM-DD HH:mm:ss');
-            var final_date = moment($("#final_date").data("date"), "DD-MM-YYYY").endOf('day').format('YYYY-MM-DD HH:mm:ss');
-            var pointsale_id = $('#pointsale_id').val();
-
-            App.blockUI({
-                 target: $("#sellers_div"),
-                 animate: true
-            });
-
-            $.ajax({
-              type: "get",
-              url:  '/find_sellers_by_date/' + pointsale_id+ '/' + initial_date + '/' + final_date,
-              dataType: 'json',
-              success: function(data) {
-                  console.log(data);
-                  $('#sellers_ids').html('');
-                  for (var i = 0; i < data.length; i++) {
-                    $('#sellers_ids').append($('<option>', {
-                        value: data[i].seller_id,
-                        text : data[i].name
-                    }));
-                  }
-                  $('#sellers_ids').multiselect('refresh');
-                  App.unblockUI($("#sellers_div"));
-                  $('#generate_button').prop('disabled', false);
-              },
-                error: function (err) {
-                    App.unblockUI($("#sellers_div"));
-                    toastr["error"]('Ya se generaron comisiones para el periodo seleccionado');
-                }
-            });
-
-        } else {
-            toastr["error"]('Seleccione punto de venta y rango de fechas');
+      $.ajax({
+        type: "get",
+        url: '/find_sellers_by_date/' + pointsale_id + '/' + initial_date + '/' + final_date,
+        dataType: 'json',
+        success: function(data) {
+          $('#sellers_ids').html('');
+          for (var i = 0; i < data.length; i++) {
+            $('#sellers_ids').append($('<option>', {
+              value: data[i].seller_id,
+              text : data[i].name
+            }));
+          }
+          $('#sellers_ids').multiselect('refresh');
+          App.unblockUI($("#sellers_div"));
+          $('#generate_button').prop('disabled', false);
+        },
+        error: function (err) {
+          App.unblockUI($("#sellers_div"));
+          toastr["error"]('Ya se generaron comisiones para el periodo seleccionado');
         }
+      });
+
+    } else {
+        toastr["error"]('Seleccione punto de venta y rango de fechas');
     }
+  }
 
-    function generateCommissions() {
-       if($('#sellers_ids').val()) {
-            var initial_date = moment($("#initial_date").data("date"), "DD-MM-YYYY").startOf('day').format('YYYY-MM-DD HH:mm:ss');
-            var final_date = moment($("#final_date").data("date"), "DD-MM-YYYY").endOf('day').format('YYYY-MM-DD HH:mm:ss');
-            $.ajax({
-              type: "get",
-              url:  '/generate_commissions/',
-              dataType: 'script',
-              data: {
-                sellers_ids: $('#sellers_ids').val(),
-                pointsale_id: $('#pointsale_id').val(),
-                initial_date: initial_date,
-                final_date: final_date
-              },
-              success: function(data) {
-              }
-            });
-       } else {
-            toastr["error"]('Seleccione vendedores para generar comisiones');
-       }
+  function generateCommissions() {
+    if($('#sellers_ids').val()) {
+      var initial_date = moment($("#initial_date").data("date"), "DD-MM-YYYY").startOf('day').format('YYYY-MM-DD HH:mm:ss');
+      var final_date = moment($("#final_date").data("date"), "DD-MM-YYYY").endOf('day').format('YYYY-MM-DD HH:mm:ss');
+      $.ajax({
+        type: "get",
+        url: '/generate_commissions/',
+        dataType: 'script',
+        data: {
+          sellers_ids: $('#sellers_ids').val(),
+          pointsale_id: $('#pointsale_id').val(),
+          initial_date: initial_date,
+          final_date: final_date
+        },
+        success: function(data) {
+        }
+      });
+    } else {
+      toastr["error"]('Seleccione vendedores para generar comisiones');
     }
+  }
 </script>

+ 58 - 72
app/views/customers/customer_sales.html.erb

@@ -85,9 +85,9 @@
 																		</span>
 																	</div>
 																</div>
-															<button class="btn btn-icon-only blue" style="margin-left:25px" onclick="salesByDate()">
-																<i class="fa fa-search"></i>
-															</button>
+																<button class="btn btn-icon-only blue" style="margin-left:25px" onclick="salesByDate()">
+																	<i class="fa fa-search"></i>
+																</button>
 															</div>
 														</div>
 													</div>
@@ -99,7 +99,7 @@
 														<tr>
 															<th>#</th>
 															<th>Código de venta</th>
-															<% if current_user.usertype == 'A' %>
+															<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
 																<th>Punto de venta</th>
 															<% end %>
 															<th>Vendedor</th>
@@ -113,67 +113,54 @@
 															<th width="15%">Acciones</th>
 														</tr>
 													</thead>
-													<tbody id="customer_sales" >
-													<% @sales.each_with_index do |sale, key| %>
-														<tr class=<%= (sale.cancelled? ? 'danger' : (sale.paid? ? 'success' : '')) %>>
-															<td><%= sale.id %></td>
-															<td><%= sale.sale_code %> </td>
-															<% if current_user.usertype == 'A' %>
-																<td> <%= sale.get_pointsale.name %> </td>
-															<% end %>
-															<td><%= sale.user.first_name %> </td>
-															<td><%= l(sale.date_sale, :format => '%d/%m/%Y') %></td>
-															<td>
-															<% if sale.saletype == "credit" && sale.credit_note.blank? %>
-																Crédito
-															<% elsif sale.saletype == "credit" && sale.credit_note.present? %>
-																Crédito/vale
-															<% else %>
-																Contado
-															<% end %>
-															</td>
-															<td><%= sale.products.count %></td>
-															<td>
-															<% case sale.status %>
-																<% when "paid"%>
-																	<span class="label label-success"> PAGADA </span>
-																<% when "cancelled"%>
-																	<span class="label label-danger"> CANCELADO </span>
-																<% when "parcial"%>
-																	<span class="label label-warning"> ABONADA </span>
-																<% when "notpaid"%>
-																	<span class="label label-default"> PENDIENTE PAGO </span>
-															<% end %>
-															</td>
-															<td><%= number_to_currency(sale.total, precision: 2) %></td>
-
-															<% credito = Credit.where(:sale_id => sale.id).first %>
-
-															<% if credito.present? %>
-																<% abonos = CreditPayment.where(:credit_id => credito.id, :status => 0).sum(:quantity) %>
-																<% if abonos.present? %>
-																	<td><%= number_to_currency(abonos, precision: 2) %></td>
+													<tbody id="customer_sales">
+														<% @sales.each_with_index do |sale, key| %>
+															<tr class=<%= (sale.cancelled? ? 'danger' : (sale.paid? ? 'success' : '')) %>>
+																<td><%= sale.id %></td>
+																<td><%= sale.sale_code %> </td>
+																<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+																	<td> <%= sale.get_pointsale.name %> </td>
 																<% end %>
-																<td><%= number_to_currency(credito.rest, precision: 2) %></td>
-															<% else %>
-																<td></td>
-																<td></td>
-															<% end %>
-
-															<td class="text-center">
-																<%= link_to sale, {:class=>"btn btn-icon-only default", :title=>"Ver venta"} do %>
-																	<i class="fa fa-search"></i>
+																<td><%= sale.user.first_name %> </td>
+																<td><%= l(sale.date_sale, :format => '%d/%m/%Y') %></td>
+																<td>
+																	<% if sale.saletype == "credit" && sale.credit_note.blank? %>
+																		Crédito
+																	<% elsif sale.saletype == "credit" && sale.credit_note.present? %>
+																		Crédito/vale
+																	<% else %>
+																		Contado
+																	<% end %>
+																</td>
+																<td><%= sale.products.count %></td>
+																<td><%= sale_status(sale) %></td>
+																<td><%= number_to_currency(sale.total, precision: 2) %></td>
+																<% credito = Credit.where(:sale_id => sale.id).first %>
+																<% if credito.present? %>
+																	<% abonos = CreditPayment.where(:credit_id => credito.id, :status => 0).sum(:quantity) %>
+																	<% if abonos.present? %>
+																		<td><%= number_to_currency(abonos, precision: 2) %></td>
+																	<% end %>
+																	<td><%= number_to_currency(credito.rest, precision: 2) %></td>
+																<% else %>
+																	<td></td>
+																	<td></td>
 																<% end %>
-															<% if can? :destroy, Sale %>
-																<% daysToCancel = @pos_config.days_cancel_sale %>
-																	<% if (sale.date_sale + daysToCancel.days >= Date.today) && !sale.cancelled? %>
-																		<%= link_to sale , method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar venta", data: { confirm: '¿Esta seguro que desea cancelar la venta?'}   do %> <i class="fa fa-ban"></i>
+
+																<td class="text-center">
+																	<%= link_to sale, {:class=>"btn btn-icon-only default", :title=>"Ver venta"} do %>
+																		<i class="fa fa-search"></i>
+																	<% end %>
+																	<% if can? :destroy, Sale %>
+																		<% daysToCancel = @pos_config.days_cancel_sale %>
+																		<% if (sale.date_sale + daysToCancel.days >= Date.today) && !sale.cancelled? %>
+																			<%= link_to sale , method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar venta", data: { confirm: '¿Está seguro que desea cancelar la venta?' } do %> <i class="fa fa-ban"></i>
+																			<% end %>
 																		<% end %>
 																	<% end %>
-															<% end %>
-															</td>
-														</tr>
-													<% end %>
+																</td>
+															</tr>
+														<% end %>
 													</tbody>
 												</table>
 												</div>
@@ -212,11 +199,10 @@
 																		<span class="label label-success"> ACTIVO </span>
 																	<% end %>
 																</td>
-
 																<td class="text-center">
 																<% if !abono.cancelled? && abono.cash_registers_move.present? && abono.cash_registers_move.open_cash_register.open?%>
-																		<%= link_to cash_move_delete_payment_path(:credit_payment_id => abono.id, :credit => credit.id) , method: :delete_credit_payment, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar abono", data: { confirm: '¿Esta seguro que desea cancelar el abono?'}   do %> <i class="fa fa-ban"></i>
-																		<% end %>
+																	<%= link_to cash_move_delete_payment_path(:credit_payment_id => abono.id, :credit => credit.id) , method: :delete_credit_payment, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar abono", data: { confirm: '¿Está seguro que desea cancelar el abono?' } do %> <i class="fa fa-ban"></i>
+																	<% end %>
 																<% end %>
 																</td>
 															</tr>
@@ -269,20 +255,20 @@
 		var end = moment($("#end_date").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
 		var cliente = '<%= @custom.id %>'
 		App.blockUI({
-				 target: $("#sales_table"),
-				 animate: true
+			target: $("#sales_table"),
+			animate: true
 		});
 		$.ajax({
 			type: "get",
 			url:  '/find_customer_sales_by_date/' + start + '/' + end + '/' + cliente,
 			dataType: 'script',
 			success: function(data) {
-					window.setTimeout(function() {
-						App.unblockUI($("#sales_table"));
-						var startDate = moment($("#begin_date").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY')
-						var endDate = moment($("#end_date").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY');
-						$('#title_for_print').val('Ventas del ' + startDate + ' al ' + endDate);
-					}, 100);
+				window.setTimeout(function() {
+					App.unblockUI($("#sales_table"));
+					var startDate = moment($("#begin_date").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY')
+					var endDate = moment($("#end_date").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY');
+					$('#title_for_print').val('Ventas del ' + startDate + ' al ' + endDate);
+				}, 100);
 			}
 		});
 	}

+ 78 - 78
app/views/dashboard/_dashboard_for_admin.html.erb

@@ -1,104 +1,104 @@
 <div class="row">
-    <div class="col-md-12">
-        <div class="col-md-6">
-            <div class="portlet light">
-                <div class="portlet-title">
-                    <div class="caption caption-md">
-                        <i class="icon-bar-chart font-red"></i>
-                        <span class="caption-subject font-red uppercase bold">Ingresos por punto de venta</span>
-                    </div>
-                    <div class="actions">
-                        <div class="btn-group btn-group-devided" data-toggle="buttons">
-                            <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm active">
-                                <input type="radio" name="optionsIncomings" class="toggle" value="day">Día
-                            </label>                        
-                            <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm">
-                                <input type="radio" name="optionsIncomings" class="toggle" value="week">Semana
-                            </label>
-                            <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm">
-                                <input type="radio" name="optionsIncomings" class="toggle" value="month">Mes
-                            </label>
-                        </div>
-                    </div>
-                </div>
-                    <div id="incomingsByPointsaleChart" class="chart" style="width:100%;height:400px;font-size:11px;"></div>
+  <div class="col-md-12">
+    <div class="col-md-6">
+      <div class="portlet light">
+        <div class="portlet-title">
+          <div class="caption caption-md">
+            <i class="icon-bar-chart font-red"></i>
+            <span class="caption-subject font-red uppercase bold">Ingresos por punto de venta</span>
+          </div>
+          <div class="actions">
+            <div class="btn-group btn-group-devided" data-toggle="buttons">
+              <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm active">
+                <input type="radio" name="optionsIncomings" class="toggle" value="day">Día
+              </label>
+              <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm">
+                <input type="radio" name="optionsIncomings" class="toggle" value="week">Semana
+              </label>
+              <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm">
+                <input type="radio" name="optionsIncomings" class="toggle" value="month">Mes
+              </label>
             </div>
+          </div>
         </div>
+          <div id="incomingsByPointsaleChart" class="chart" style="width:100%;height:400px;font-size:11px;"></div>
+      </div>
+    </div>
 
-        <div class="col-md-6">
-            <div class="portlet light">
-                <div class="portlet-title">
-                    <div class="caption caption-md">
-                        <i class="icon-bar-chart font-red"></i>
-                        <span class="caption-subject font-red uppercase bold">10 productos mas vendidos</span>
-                    </div>
-                    <div class="actions">
-                        <div class="btn-group btn-group-devided" data-toggle="buttons">
-                            <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm active">
-                                <input type="radio" name="optionsRanking" class="toggle" value="week">Semana
-                            </label>
-                            <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm">
-                                <input type="radio" name="optionsRanking" class="toggle" value="month">Mes
-                            </label>
-                        </div>
-                    </div>
-                </div>
-                 <div id="productRankingChart" class="chart" style="width:100%;height:400px;font-size:11px;"></div>
+    <div class="col-md-6">
+      <div class="portlet light">
+        <div class="portlet-title">
+          <div class="caption caption-md">
+            <i class="icon-bar-chart font-red"></i>
+            <span class="caption-subject font-red uppercase bold">10 productos mas vendidos</span>
+          </div>
+          <div class="actions">
+            <div class="btn-group btn-group-devided" data-toggle="buttons">
+              <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm active">
+                <input type="radio" name="optionsRanking" class="toggle" value="week">Semana
+              </label>
+              <label class="btn btn-transparent grey-salsa btn-outline btn-circle btn-sm">
+                <input type="radio" name="optionsRanking" class="toggle" value="month">Mes
+              </label>
             </div>
+          </div>
         </div>
+         <div id="productRankingChart" class="chart" style="width:100%;height:400px;font-size:11px;"></div>
+      </div>
     </div>
+  </div>
 </div>
 
 <script type="text/javascript">
 $(document).on("page:change", function() {
-    // ingresos por punto de venta
-    MakeChart('serial', <%= @incomings %>, 'incomingsByPointsaleChart', 'pointsale', 'total');
-    // ranking de productos
-    MakeChart('pie', <%= @product_ranking %>, 'productRankingChart', 'product', 'quantity');    
+  // ingresos por punto de venta
+  MakeChart('serial', <%= @incomings %>, 'incomingsByPointsaleChart', 'pointsale', 'total');
+  // ranking de productos
+  MakeChart('pie', <%= @product_ranking %>, 'productRankingChart', 'product', 'quantity');
 });
 
 
 $('input:radio[name=optionsIncomings]').change(function() {
-    var period = $('input:radio[name=optionsIncomings]:checked').val();
-    getChart('incomings', period);
+  var period = $('input:radio[name=optionsIncomings]:checked').val();
+  getChart('incomings', period);
 });
 
 $('input:radio[name=optionsRanking]').change(function() {
-    var period = $('input:radio[name=optionsRanking]:checked').val();
-    getChart('products', period);
+  var period = $('input:radio[name=optionsRanking]:checked').val();
+  getChart('products', period);
 });
 
 setTimeout(function() {
-    $('.chart a').remove();
+  $('.chart a').remove();
 }, 1000);
 
 
 function getChart(chart, period) {
-    App.blockUI({
-         target: $((chart == "incomings" ? "#incomingsByPointsaleChart" : "#productRankingChart")),
-         animate: true
-    });
-    $.ajax({
-      type: "get",
-      url:  '/get_chart_data_for_dashboard/',
-      data: {
-        period: period,
-        chart: chart
-      },
-      dataType: 'text',
-      success: function(data) {
-          var data = JSON.parse(data);
-          window.setTimeout(function() {
-            App.unblockUI($((chart == "incomings" ? "#incomingsByPointsaleChart" : "#productRankingChart")));
-            
-            if (chart == 'incomings') {
-                MakeChart('serial', data, 'incomingsByPointsaleChart', 'pointsale', 'total');
-            } else {
-                MakeChart('pie', data, 'productRankingChart', 'product', 'quantity');
-            }
-            $('.chart a').remove();
-          }, 100);
-      }
-    });    
+  App.blockUI({
+    target: $((chart == "incomings" ? "#incomingsByPointsaleChart" : "#productRankingChart")),
+    animate: true
+  });
+  $.ajax({
+    type: "get",
+    url:  '/get_chart_data_for_dashboard/',
+    data: {
+    period: period,
+    chart: chart
+    },
+    dataType: 'text',
+    success: function(data) {
+      var data = JSON.parse(data);
+      window.setTimeout(function() {
+        App.unblockUI($((chart == "incomings" ? "#incomingsByPointsaleChart" : "#productRankingChart")));
+
+        if (chart == 'incomings') {
+          MakeChart('serial', data, 'incomingsByPointsaleChart', 'pointsale', 'total');
+        } else {
+          MakeChart('pie', data, 'productRankingChart', 'product', 'quantity');
+        }
+        $('.chart a').remove();
+      }, 100);
+    }
+  });
 }
-</script>
+</script>

+ 1 - 1
app/views/dashboard/index.html.erb

@@ -40,7 +40,7 @@
 							</div>
 						<% end %>
 					</div>
-					<% if current_user.usertype == 'A' %>
+					<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
 						<%= render 'dashboard/dashboard_for_admin' %>
 					<% elsif current_user.usertype == 'G' %>
 						<%= render 'dashboard/dashboard_for_manager' %>

+ 25 - 0
app/views/errors/internal_server_error.html.erb

@@ -0,0 +1,25 @@
+<div class="page-container">
+  <div class="page-content-wrapper">
+    <div class="page-head">
+      <div class="container-fluid">
+        <div class="page-title">
+          <h1>Error del sistema </h1>
+        </div>
+      </div>
+    </div>
+    <div class="page-content">
+      <div class="container-fluid">
+        <div class="row">
+          <div class="col-md-12">
+            <div class="portlet light bordered">
+              <div class="portlet-body">
+                Por favor contacte al administrador del sistema. </span>
+                <%= render "supports/contact_support" %>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 11 - 0
app/views/errors/not_found.html.erb

@@ -0,0 +1,11 @@
+<div class="page-container">
+  <div class="page-content-wrapper">
+    <div class="page-head">
+      <div class="container-fluid">
+        <div class="page-title">
+          <h1>No se encontró la página </h1>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 54 - 54
app/views/expenses/_expenses_for_admin.html.erb

@@ -2,10 +2,10 @@
   <div class="col-md-2 col-sm-3 col-xs-3">
     <ul class="nav nav-tabs tabs-left">
       <li class="active">
-          <a href="#puntosdeventa" data-toggle="tab"> Puntos de venta </a>
+        <a href="#puntosdeventa" data-toggle="tab"> Puntos de venta </a>
       </li>
       <li>
-          <a href="#generales" data-toggle="tab"> Generales </a>
+        <a href="#generales" data-toggle="tab"> Generales </a>
       </li>
     </ul>
   </div>
@@ -18,10 +18,10 @@
               <thead>
                 <tr>
                   <th>#</th>
-                  <th>Código de egreso</th>
-                  <th>Concepto de egreso</th>
-                  <th>Punto de venta</th>
-                  <th>Caja registradora</th>
+                  <th>Código<br>de egreso</th>
+                  <th>Concepto<br>de egreso</th>
+                  <th>Punto<br>de venta</th>
+                  <th>Caja<br>registradora</th>
                   <th>Fecha</th>
                   <th>Cantidad</th>
                   <th>Observaciones</th>
@@ -31,31 +31,31 @@
               </thead>
               <tbody>
                 <% @from_pointsale.each_with_index do |expense, key| %>
-                <tr>
-                  <td><%= expense.id %></td>
-                  <td><%= expense.expense_code %></td>
-                  <td><%= expense.expensesconcept.name %></td>
-                  <td><%= expense.open_cash_register.cash_register.pointsale.name %></td>
-                  <td><%= expense.open_cash_register.cash_register.name %></td>
-                  <td><%= l(expense.created_at, :format => '%d/%B/%Y') %> </td>
-                  <td><%= number_to_currency(expense.quantity, precision: 2) %> </td>
-                  <td><%= expense.observations %> </td>
-                  <td>
-                    <% case expense.status %>
-                    <% when "active"%>
-                      <span class="label label-sm label-warning"> <i class="fa fa-clock-o"></i> Caja abierta </span>
-                    <% when "canceled"%>
-                       <span class="label label-sm label-danger"> <i class="fa fa-close"></i> Cancelada </span>
-                    <% when "registered"%>
-                       <span class="label label-sm label-success"><i class="fa fa-check"></i>  Caja cerrada </span>
-                    <% end %>
-                  </td>
-                  <td class="text-center">
-                    <% if expense.status == "active" %>
-                      <%= link_to expense, method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar egreso", data: { confirm: '¿Está seguro que desea cancelar el egreso?' } do %> <i class="fa fa-ban"></i><% end %>
-                    <% end %>
-                  </td>
-                </tr>
+                  <tr>
+                    <td><%= expense.id %></td>
+                    <td><%= expense.expense_code %></td>
+                    <td><%= expense.expensesconcept.name %></td>
+                    <td><%= expense.open_cash_register.cash_register.pointsale.name %></td>
+                    <td><%= expense.open_cash_register.cash_register.name %></td>
+                    <td><%= l(expense.created_at, format: '%d/%B/%Y') %> </td>
+                    <td><%= number_to_currency(expense.quantity, precision: 2) %> </td>
+                    <td><%= expense.observations %> </td>
+                    <td>
+                      <% case expense.status %>
+                      <% when "active"%>
+                        <span class="label label-sm label-warning"> <i class="fa fa-clock-o"></i> Caja abierta </span>
+                      <% when "canceled"%>
+                         <span class="label label-sm label-danger"> <i class="fa fa-close"></i> Cancelada </span>
+                      <% when "registered"%>
+                         <span class="label label-sm label-success"><i class="fa fa-check"></i>  Caja cerrada </span>
+                      <% end %>
+                    </td>
+                    <td class="text-center">
+                      <% if expense.active? %>
+                        <%= link_to expense, method: :delete, class: "btn btn-icon-only btn-danger", title: "Cancelar egreso", data: { confirm: '¿Está seguro que desea cancelar el egreso?' } do %> <i class="fa fa-ban"></i><% end %>
+                      <% end %>
+                    </td>
+                  </tr>
                 <% end %>
               </tbody>
             </table>
@@ -69,8 +69,8 @@
               <thead>
                 <tr>
                   <th>#</th>
-                  <th>Código de egreso</th>
-                  <th>Concepto de gasto</th>
+                  <th>Código<br>de egreso</th>
+                  <th>Concepto<br>de gasto</th>
                   <th>Fecha</th>
                   <th>Cantidad</th>
                   <th>Observaciones</th>
@@ -80,27 +80,27 @@
               </thead>
               <tbody>
                 <% @general_expenses.each_with_index do |expense, key| %>
-                <tr>
-                  <td><%= expense.id %></td>
-                  <td><%= expense.expense_code %></td>
-                  <td><%= expense.expensesconcept.name %></td>
-                  <td><%= l(expense.expense_date, :format => '%d/%B/%Y') %> </td>
-                  <td><%= number_to_currency(expense.quantity, precision: 2) %> </td>
-                  <td><%= expense.observations %> </td>
-                  <td>
-                    <% case expense.status %>
-                    <% when "active"%>
-                      <span class="label label-sm label-success"> <i class="fa fa-check"></i> Activo </span>
-                    <% when "canceled"%>
-                       <span class="label label-sm label-danger"> <i class="fa fa-close"></i> Cancelado </span>
-                    <% end %>
-                  </td>
-                  <td class="text-center">
-                    <% if expense.active? %>
-                      <%= link_to expense, method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar egreso", data: { confirm: '¿Está seguro que desea cancelar el egreso?' } do %> <i class="fa fa-ban"></i><% end %>
-                    <% end %>
-                  </td>
-                </tr>
+                  <tr>
+                    <td><%= expense.id %></td>
+                    <td><%= expense.expense_code %></td>
+                    <td><%= expense.expensesconcept.name %></td>
+                    <td><%= l(expense.expense_date, format: '%d/%B/%Y') %> </td>
+                    <td><%= number_to_currency(expense.quantity, precision: 2) %> </td>
+                    <td><%= expense.observations %> </td>
+                    <td>
+                      <% case expense.status %>
+                      <% when "active"%>
+                        <span class="label label-sm label-success"> <i class="fa fa-check"></i> Activo </span>
+                      <% when "canceled"%>
+                         <span class="label label-sm label-danger"> <i class="fa fa-close"></i> Cancelado </span>
+                      <% end %>
+                    </td>
+                    <td class="text-center">
+                      <% if expense.active? %>
+                        <%= link_to expense, method: :delete, class: "btn btn-icon-only btn-danger", title: "Cancelar egreso", data: { confirm: '¿Está seguro que desea cancelar el egreso?' } do %> <i class="fa fa-ban"></i> <% end %>
+                      <% end %>
+                    </td>
+                  </tr>
                 <% end %>
               </tbody>
             </table>

+ 2 - 2
app/views/expenses/_expenses_for_manager.html.erb

@@ -33,8 +33,8 @@
         <% end %>
       </td>
       <td class="text-center">
-        <% if expense.status == "active" %>
-          <%= link_to expense , method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar egreso", data: { confirm: '¿Esta seguro que desea cancelar el egreso?'}   do %> <i class="fa fa-ban"></i><% end %>
+        <%= expense.active? %>
+          <%= link_to expense, method: :delete, class: "btn btn-icon-only btn-danger", title: "Cancelar egreso", data: { confirm: '¿Está seguro que desea cancelar el egreso?' } do %> <i class="fa fa-ban"></i><% end %>
         <% end %>
       </td>
     </tr>

+ 68 - 80
app/views/expenses/_form.html.erb

@@ -1,97 +1,86 @@
-<!-- BEGIN FORM-->
-<%= form_for(@expense, :html => {:class=>"form-horizontal"}) do |f| %>
-<div class="portlet-body form">
-  <% if @expense.errors.any? %>
-    <div class="alert alert-danger">
-      <strong>Tiene <%= pluralize(@expense.errors.count, "error") %> no se puede guardar el gasto</strong><br>
-    </div>
-  <% end %>
-  <div class="form-body">
-    <div class="row">
-      <div class="col-md-8">
-        <%= hidden_field_tag :concept_purchase_payment, @concept_purchase_payment.id %>
-        <div class="form-group">
-          <%= f.label :expense_code, {:class=>"col-md-3 control-label"} do %> Código de egreso
-          <span class="required">*</span>
-          <% end %>
-          <div class="col-md-4 input-group">
-            <span class="input-group-addon"><i class="fa fa-barcode"></i></span>
-            <%= f.text_field :expense_code, { :class=>"form-control", :readonly => true} %>
-          </div>
-        </div>
-        <% if current_user.usertype == "A" %>
+<%= form_for(@expense, html: { class: "form-horizontal" }) do |f| %>
+  <div class="portlet-body form">
+    <% if @expense.errors.any? %>
+      <div class="alert alert-danger">
+        <strong>Tiene <%= pluralize(@expense.errors.count, "error") %> no se puede guardar el gasto</strong><br>
+      </div>
+    <% end %>
+    <div class="form-body">
+      <div class="row">
+        <div class="col-md-8">
+          <%= hidden_field_tag :concept_purchase_payment, @concept_purchase_payment.id %>
           <div class="form-group">
-            <%= f.label :expense_date, "Fecha", {:class=>"col-md-3 control-label"} do %> Fecha
-            <span class="required">*</span>
-            <% end %>
-                <div class="col-sm-4" style="padding-left:0px;padding-right:0px;">
-                    <div class='input-group date' id='datetimepicker1'>
-                        <span class="input-group-addon">
-                            <span class="glyphicon glyphicon-calendar"></span>
-                        </span>
-                        <%= f.text_field :expense_date, class: 'form-control'%>
-                    </div>
-                </div>
+            <%= f.label :expense_code, { class: "col-md-3 control-label" } do %> Código de egreso <span class="required">*</span> <% end %>
+            <div class="col-md-4 input-group">
+              <span class="input-group-addon"><i class="fa fa-barcode"></i></span>
+              <%= f.text_field :expense_code, { class: "form-control", readonly: true } %>
+            </div>
           </div>
-        <% end %>
-        <% if current_user.usertype != "A" %>
+          <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+            <div class="form-group">
+              <%= f.label :expense_date, "Fecha", { class: "col-md-3 control-label" } do %> Fecha <span class="required">*</span> <% end %>
+              <div class="col-sm-4" style="padding-left:0px;padding-right:0px;">
+                <div class='input-group date' id='datetimepicker1'>
+                  <span class="input-group-addon">
+                    <span class="glyphicon glyphicon-calendar"></span>
+                  </span>
+                  <%= f.text_field :expense_date, class: 'form-control' %>
+                </div>
+              </div>
+            </div>
+          <% else %>
+            <div class="form-group">
+              <%= f.label :open_cash_register_id, "Caja registradora", { class: "col-md-3 control-label" } do %> Caja registradora <span class="required">*</span> <% end %>
+              <div class="input-group col-md-4 select2-bootstrap-prepend">
+                <%= f.select :open_cash_register_id, @current_user.pointsale.open_cash_registers.abiertas.map{ |o| [o.cash_register.name, o.id] }, { prompt: "Seleccione" }, { class: 'form-control select2', disabled: @is_cashier } %>
+                <% if current_user.usertype == 'C' %>
+                  <%= f.hidden_field :open_cash_register_id %>
+                <% end %>
+              </div>
+            </div>
+          <% end %>
           <div class="form-group">
-            <%= f.label :open_cash_register_id, "Caja registradora", {:class=>"col-md-3 control-label"} do %> Caja registradora
+            <%= f.label :expensesconcept_id, "Concepto", { class: "col-md-3 control-label" } do %>Concepto de egreso <span class="required">*</span> <% end %>
+            <div class="input-group col-md-4 select2-bootstrap-prepend">
+              <%= f.collection_select :expensesconcept_id, @expenses_concepts, :id, :name, { prompt: "Seleccione" }, { class: "form-control select2", style: "width: 100%" } %>
+            </div>
+          </div>
+          <div class="form-group hidden" id="purchases_div">
+            <%= f.label :purchases, "Concepto", { class: "col-md-3 control-label" } do %>Compras
             <span class="required">*</span>
             <% end %>
             <div class="input-group col-md-4 select2-bootstrap-prepend">
-              <%= f.select :open_cash_register_id, @current_user.pointsale.open_cash_registers.abiertas.map{|o| [o.cash_register.name, o.id]}, {:prompt => "Seleccione"}, { :class => 'form-control select2', :disabled => @is_cashier} %>
-              <% if current_user.usertype == 'C' %>
-                <%= f.hidden_field :open_cash_register_id %>
+              <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+                <%= select_tag "purchases", options_from_collection_for_select(Purchase.notpaid, :id, :code_with_price), include_blank: "Seleccione", class: "form-control select2" %>
+              <% else %>
+                <%= select_tag "purchases", options_from_collection_for_select(Purchase.notpaid.where(pointsale_id: current_user.pointsale_id), :id, :code_with_price), include_blank: "Seleccione", class: "form-control select2" %>
               <% end %>
             </div>
           </div>
-        <% end %>
-        <div class="form-group">
-          <%= f.label :expensesconcept_id, "Concepto", {:class=>"col-md-3 control-label"} do %>Concepto de egreso
-          <span class="required">*</span>
-          <% end %>
-          <div class="input-group col-md-4 select2-bootstrap-prepend">
-            <%= f.collection_select :expensesconcept_id, @expenses_concepts, :id, :name, {:prompt => "Seleccione"}, {:class => "form-control select2", :style => "width: 100%"} %>
-          </div>
-        </div>
-
-        <div class="form-group hidden" id="purchases_div">
-          <%= f.label :purchases, "Concepto", {:class=>"col-md-3 control-label"} do %>Compras
-          <span class="required">*</span>
-          <% end %>
-          <div class="input-group col-md-4 select2-bootstrap-prepend">
-            <% if current_user.usertype == 'A' %>
-              <%= select_tag "purchases", options_from_collection_for_select(Purchase.notpaid, :id, :code_with_price), :include_blank => "Seleccione",  class: "form-control select2" %>
-            <% else %>
-              <%= select_tag "purchases", options_from_collection_for_select(Purchase.notpaid.where(:pointsale_id => current_user.pointsale_id), :id, :code_with_price), :include_blank => "Seleccione",  class: "form-control select2" %>
+          <div class="form-group">
+            <%= f.label :quantity, { class: "col-md-3 control-label" } do %>Cantidad <span class="required">*</span>
             <% end %>
+            <div class="col-md-4" style="padding-left:0px;padding-right:0px">
+              <%= f.number_field :quantity, { class: "form-control" } %>
+            </div>
           </div>
-        </div>
-        <div class="form-group">
-          <%= f.label :quantity,  {:class=>"col-md-3 control-label"} do %>Cantidad <span class="required">*</span>
-          <% end %>
-          <div class="col-md-4" style="padding-left:0px;padding-right:0px">
-            <%= f.number_field :quantity, {:class=>"form-control" }  %>
-          </div>
-        </div>
-        <div class="form-group">
-          <%= f.label :observations, "Observaciones", {:class=>"col-md-3 control-label"} %>
-          <div class="col-md-9" style="padding-left:0px">
-            <%= f.text_area :observations, {:class=>"form-control", :rows=>5} %>
+          <div class="form-group">
+            <%= f.label :observations, "Observaciones", { class: "col-md-3 control-label" } %>
+            <div class="col-md-9" style="padding-left:0px">
+              <%= f.text_area :observations, { class: "form-control", rows: 5 } %>
+            </div>
           </div>
-        </div>
+      </div>
     </div>
-  </div>
-  <div class="form-actions">
-    <div class="row">
-      <div class="col-md-9">
-        <%= f.submit 'Guardar', {:class=>"btn green"} %>
-        <%= link_to 'Cancelar', expenses_path, {:class=>"btn default"} %>
+    <div class="form-actions">
+      <div class="row">
+        <div class="col-md-9">
+          <%= f.submit 'Guardar', { class: "btn green" } %>
+          <%= link_to 'Cancelar', expenses_path, { class: "btn default" } %>
+        </div>
       </div>
     </div>
   </div>
-</div>
 <% end %>
 <script type="text/javascript">
   $(document).on('page:change', function() {
@@ -126,7 +115,7 @@
     });
 
   function generateExpenseCode() {
-    <% if current_user.usertype == 'A' %>
+    <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
       $.ajax({
         type: "get",
         url:  '/get_next_expense_code/0',
@@ -149,4 +138,3 @@
     <% end %>
   }
 </script>
-

+ 3 - 3
app/views/expenses/index.html.erb

@@ -44,13 +44,13 @@
                   </div>
                   <div class="actions">
                     <% if can? :create, Expense %>
-                    <%= link_to new_expense_path, {:class=>"btn bold green pull-right"} do %> Nuevo egreso <i class="fa fa-plus"></i>
-                    <% end %>
+                      <%= link_to new_expense_path, {:class=>"btn bold green pull-right"} do %> Nuevo egreso <i class="fa fa-plus"></i>
+                      <% end %>
                     <% end %>
                   </div>
                 </div>
                 <div class="portlet-body">
-                  <% if current_user.usertype == "A" %>
+                  <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
                     <%= render partial: 'expenses/expenses_for_admin' %>
                   <% else %>
                     <%= render partial: 'expenses/expenses_for_manager' %>

+ 66 - 67
app/views/expensesconcepts/_form.html.erb

@@ -1,78 +1,78 @@
-<%= form_for(@expensesconcept, :html => {:class=>"form-horizontal"}) do |f| %>
-
-<div class="portlet-body form">
-	<% if @expensesconcept.errors.any? %>
-	<div class="alert alert-danger">
-		<strong>Tiene <%= pluralize(@expensesconcept.errors.count, "error") %> no se puede guardar el concepto de egreso</strong><br>
-	</div>
-	<% end %>
-	<div class="form-body">
-		<div class="form-group">
-			<%= f.label :name, "Nombre del Concepto", {:class=>"col-md-3 control-label"} do %> Nombre del concepto
-				<span class="required">*</span>
-			<% end %>
-			<div class="col-md-9">
-				<%= f.text_field :name, {:class=>"form-control"} %>
-			</div>
+<%= form_for(@expensesconcept, html: { class: "form-horizontal" }) do |f| %>
+	<div class="portlet-body form">
+		<% if @expensesconcept.errors.any? %>
+		<div class="alert alert-danger">
+			<strong>Tiene <%= pluralize(@expensesconcept.errors.count, "error") %> no se puede guardar el concepto de egreso</strong><br>
 		</div>
-		<div class="form-group">
-			<%= f.label :decription, "Descripción", {:class=>"col-md-3 control-label"} %>
-			<div class="col-md-9">
-				<%= f.text_field :description, {:class=>"form-control"} %>
+		<% end %>
+		<div class="form-body">
+			<div class="form-group">
+				<%= f.label :name, "Nombre del Concepto", { class: "col-md-3 col-sm-3 control-label" } do %> Nombre del concepto
+					<span class="required">*</span>
+				<% end %>
+				<div class="col-md-5 col-sm-5">
+					<%= f.text_field :name, { class: "form-control" } %>
+				</div>
 			</div>
-		</div>
-		<% if @expensesconcept.persisted? %>
-		<div class="form-group">
-			<%= f.label :status, {:class=>"col-md-3 control-label"} %>
-			<div class="col-md-9">
-				<%= f.check_box(:status,
-					{
-						class: "make-switch",
-						data: {
-							on_color: "success",
-							off_color: "danger",
-							on_text: "Activo",
-							off_text: "Inactivo"
-						}
-					},
-					"active", "inactive"
-				) %>
+			<div class="form-group">
+				<%= f.label :decription, "Descripción", { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-5 col-sm-5">
+					<%= f.text_area :description, { class: "form-control", rows: 5 } %>
+				</div>
 			</div>
-		</div>
-		<% end %>
-		<div class="form-group ">
-			<%= f.label :allpoints, "Aplica a todo los puntos de venta?", {:class=>"col-md-3 control-label"} %>
-			<div class="col-md-9">
-				<%= f.check_box(:allpoints,
-					{
-						class: "make-switch",
-						data: {
-							on_color: "success",
-							off_color: "danger",
-							on_text: "Si",
-							off_text: "No"
-						}
-					},"true", "false"
-				) %>
+			<% if @expensesconcept.persisted? %>
+			<div class="form-group">
+				<%= f.label :status, { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-2 col-sm-2">
+					<%= f.check_box(:status,
+						{
+							class: "make-switch",
+							data: {
+								on_color: "success",
+								off_color: "danger",
+								on_text: "Activo",
+								off_text: "Inactivo"
+							}
+						},
+						"active", "inactive"
+					) %>
+				</div>
 			</div>
-		</div>
-		<div class="form-group" id="boxpointsales" <% if @expensesconcept.allpoints? %> style="display:none;"  <% end %> >
-			<%= f.label :pointsale_ids, "Puntos de Venta", {:class=>"col-md-3 control-label"} %>
-			<div class="col-md-9">
-				<%= f.collection_select :pointsale_ids, Pointsale.activos, :id, :name, {:selected => @expensesconcept.pointsale_ids, :include_blank => false}, {:multiple => true, :class => "multi-select "}   %>
+			<% end %>
+			<div class="form-group ">
+				<%= f.label :allpoints, "Aplica a todo los puntos de venta?", { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-2 col-sm-2">
+					<%= f.check_box(:allpoints,
+						{
+							class: "make-switch",
+							data: {
+								on_color: "success",
+								off_color: "danger",
+								on_text: "Si",
+								off_text: "No"
+							}
+						},"true", "false"
+					) %>
+				</div>
+			</div>
+			<div class="form-group" id="boxpointsales" <% if @expensesconcept.allpoints? %> style="display:none;" <% end %> >
+				<%= f.label :pointsale_ids, "Puntos de Venta", { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-5 col-sm-5">
+					<%= f.collection_select :pointsale_ids, Pointsale.activos, :id, :name, { selected: @expensesconcept.pointsale_ids, include_blank: false }, { multiple: true, class: "multi-select" } %>
+				</div>
 			</div>
 		</div>
-	</div>
-	<div class="form-actions">
-		<div class="row">
-			<div class="col-md-offset-3 col-md-9">
-				<%= f.submit 'Guardar', {:class=>"btn green"} %>
-				<%= link_to 'Cancelar', expensesconcepts_path(:filter => @filter, :current_page => @current_page), {:class=>"btn default"} %>
+		<div class="form-actions">
+			<div class="row">
+				<div class="col-md-offset-3 col-md-9">
+					<%= f.submit 'Guardar', { class: "btn green" } %>
+					<%= link_to 'Cancelar', expensesconcepts_path(filter: @filter, current_page: @current_page), { class: "btn default" } %>
+				</div>
 			</div>
 		</div>
 	</div>
-</div>
 <% end %>
+
 <script type="text/javascript">
 	$(document).ready(function() {
 		handleMultiSelect();
@@ -81,8 +81,7 @@
 		$('input[name="expensesconcept[allpoints]"]').on('switchChange.bootstrapSwitch', function(event, state) {
 			if (state) {
 				$("#boxpointsales").hide();
-
-			}else{
+			} else {
 				$("#boxpointsales").show();
 			}
 		});

+ 102 - 103
app/views/expensesconcepts/index.html.erb

@@ -1,123 +1,122 @@
-		<!-- BEGIN CONTAINER -->
-		<div class="page-container">
-			<!-- BEGIN CONTENT -->
-			<div class="page-content-wrapper">
-				<!-- BEGIN CONTENT BODY -->
-				<!-- BEGIN PAGE HEAD-->
-				<div class="page-head">
-					<div class="container-fluid">
-						<!-- BEGIN PAGE TITLE -->
-						<div class="page-title">
-							<h1>Conceptos de Egresos </h1>
-						</div>
-						<!-- END PAGE TITLE -->
-					</div>
+<!-- BEGIN CONTAINER -->
+<div class="page-container">
+	<!-- BEGIN CONTENT -->
+	<div class="page-content-wrapper">
+		<!-- BEGIN CONTENT BODY -->
+		<!-- BEGIN PAGE HEAD-->
+		<div class="page-head">
+			<div class="container-fluid">
+				<!-- BEGIN PAGE TITLE -->
+				<div class="page-title">
+					<h1>Conceptos de Egresos </h1>
 				</div>
-				<!-- END PAGE HEAD-->
-				<!-- BEGIN PAGE CONTENT BODY -->
-				<div class="page-content">
-					<div class="container-fluid">
-						<!-- BEGIN PAGE BREADCRUMBS -->
-						<ul class="page-breadcrumb breadcrumb">
-							<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
-						</ul>
-						<!-- END PAGE BREADCRUMBS -->
-						<!-- BEGIN PAGE CONTENT INNER -->
-						<div class="page-content-inner">
-							<div id="notice">
-							<% if success %>
-							<div class="alert alert-success">
-								<p><%= success %></p>
-							</div>
-							<% elsif warning %>
-							<div class="alert alert-warning">
-								<p><%= warning %></p>
-							</div>
-							<% end %>
-							</div>
-							<div class="row">
-								<div class="col-md-12">
-									<div class="portlet light ">
-										<div class="portlet-title">
-											<div class="caption">
-												<i class="fa fa-list "></i>
-												<span class="caption-subject bold uppercase">Lista de conceptos de egresos</span>
-											</div>
-											<div class="actions">
-												<% if can? :create, Expensesconcept %>
-												<%= link_to new_expensesconcept_path, {:class=>"btn bold green pull-right filtros"} do %> Nuevo Concepto de egreso <i class="fa fa-plus"></i>
+				<!-- END PAGE TITLE -->
+			</div>
+		</div>
+		<!-- END PAGE HEAD-->
+		<!-- BEGIN PAGE CONTENT BODY -->
+		<div class="page-content">
+			<div class="container-fluid">
+				<!-- BEGIN PAGE BREADCRUMBS -->
+				<ul class="page-breadcrumb breadcrumb">
+					<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
+				</ul>
+				<!-- END PAGE BREADCRUMBS -->
+				<!-- BEGIN PAGE CONTENT INNER -->
+				<div class="page-content-inner">
+					<div id="notice">
+					<% if success %>
+					<div class="alert alert-success">
+						<p><%= success %></p>
+					</div>
+					<% elsif warning %>
+					<div class="alert alert-warning">
+						<p><%= warning %></p>
+					</div>
+					<% end %>
+					</div>
+					<div class="row">
+						<div class="col-md-12">
+							<div class="portlet light ">
+								<div class="portlet-title">
+									<div class="caption">
+										<i class="fa fa-list "></i>
+										<span class="caption-subject bold uppercase">Lista de conceptos de egresos</span>
+									</div>
+									<div class="actions">
+										<% if can? :create, Expensesconcept %>
+										<%= link_to new_expensesconcept_path, {:class=>"btn bold green pull-right filtros"} do %> Nuevo Concepto de egreso <i class="fa fa-plus"></i>
+										<% end %>
+										<% end %>
+									</div>
+								</div>
+								<div class="portlet-body">
+									<input type='hidden' name='filter' id='filter' value='<%= @filter %>' >
+									<input type='hidden' name='current_page' id='current_page' value='<%= @current_page %>' >
+									<table class="table table-striped table-bordered table-hover tableadvanced">
+										<thead>
+											<tr>
+												<th>#</th>
+												<th>Nombre</th>
+												<th>Descripción</th>
+												<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+													<th>Puntos de venta</th>
 												<% end %>
+												<th>Status</th>
+												<% if can? :manage, Expensesconcept %>
+													<th>Acciones</th>
 												<% end %>
-											</div>
-										</div>
-										<div class="portlet-body">
-											<input type='hidden' name='filter' id='filter' value='<%= @filter %>' >
-											<input type='hidden' name='current_page' id='current_page' value='<%= @current_page %>' >
-											<table class="table table-striped table-bordered table-hover tableadvanced">
-												<thead>
-													<tr>
-														<th>#</th>
-														<th>Nombre</th>
-														<th>Descripción</th>
-														<% if current_user.usertype == 'A' %>
-															<th>Puntos de venta</th>
-														<% end %>
-														<th>Status</th>
-														<% if can? :manage, Expensesconcept %>
-														<th>Acciones</th>
-														<% end %>
-													</tr>
-												</thead>
-												<tbody>
-													<% @expensesconcepts.each_with_index do |expensesconcept, key| %>
-													<tr>
-														<td><%= key + 1 %></td>
-														<td><%= expensesconcept.name %></td>
-                                                        <td><%= expensesconcept.description %></td>
-                                                        <% if current_user.usertype == 'A' %>
-	                                                        <td>
-	                                                        	<% if expensesconcept.allpoints %>
-	                                                        	Todos
-	                                                        	<% else %>
-	                                                        	<%= expensesconcept.pointsales.map { |pv| pv.name }.join(", ")  %>
-	                                                        	<% end %>
-	                                                        </td>
-                                                        <% end %>
-
-														<td class="text-center"><% if expensesconcept.status == "active" %>
+											</tr>
+										</thead>
+										<tbody>
+											<% @expensesconcepts.each_with_index do |expensesconcept, key| %>
+												<tr>
+													<td><%= key + 1 %></td>
+													<td><%= expensesconcept.name %></td>
+                          <td><%= expensesconcept.description %></td>
+                          <% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+                            <td>
+                            	<% if expensesconcept.allpoints %>
+                            	Todos
+                            	<% else %>
+                            	<%= expensesconcept.pointsales.map { |pv| pv.name }.join(", ") %>
+                            	<% end %>
+                            </td>
+                          <% end %>
+													<td class="text-center">
+														<% if expensesconcept.active? %>
 															<i class="fa fa-check font-green"></i>
-															<% else %>
+														<% else %>
 															<i class="fa fa-times font-red"></i>
-															<% end %>
-														</td>
-														<% if can? :manage, Expensesconcept %>
+														<% end %>
+													</td>
+													<% if can? :manage, Expensesconcept %>
 														<td class="text-center">
-															<%= link_to edit_expensesconcept_path(expensesconcept), {:class=>"btn btn-icon-only btn-primary filtros", :title=>"Editar concepto de egreso"} do %>
+															<%= link_to edit_expensesconcept_path(expensesconcept), {:class=>"btn btn-icon-only btn-primary filtros", :title=>"Editar concepto de egreso" } do %>
 																<i class="fa fa-edit"></i>
 															<% end %>
 															<% unless @concept_purchase_payment.id == expensesconcept.id %>
-																<%= link_to expensesconcept_path(expensesconcept), method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Eliminar concepto de egreso", data: { confirm: '¿Esta seguro de eliminar el concepto de egreso?'}   do %>
+																<%= link_to expensesconcept_path(expensesconcept), method: :delete, :class => "btn btn-icon-only btn-danger", :title=>"Eliminar concepto de egreso", data: { confirm: '¿Está seguro de eliminar el concepto de egreso?' } do %>
 																	<i class="fa fa-trash-o"></i>
 																<% end %>
 															<% end %>
-
 														</td>
-														<% end %>
-													</tr>
-												<% end %>
-												</tbody>
-											</table>
-										</div>
-									</div>
+													<% end %>
+												</tr>
+											<% end %>
+										</tbody>
+									</table>
 								</div>
 							</div>
 						</div>
-						<!-- END PAGE CONTENT INNER -->
 					</div>
 				</div>
-				<!-- END PAGE CONTENT BODY -->
-				<!-- END CONTENT BODY -->
+				<!-- END PAGE CONTENT INNER -->
 			</div>
-			<!-- END CONTENT -->
 		</div>
-		<!-- END CONTAINER -->
+		<!-- END PAGE CONTENT BODY -->
+		<!-- END CONTENT BODY -->
+	</div>
+	<!-- END CONTENT -->
+</div>
+<!-- END CONTAINER -->

+ 88 - 166
app/views/layouts/application.html.erb

@@ -1,183 +1,105 @@
 <!DOCTYPE html>
 <html>
-<head>
-	<title> <%= APP_ABR %> </title>
+	<head>
+		<title> <%= APP_ABR %> </title>
+
+		<% if user_signed_in? %>
+			<!-- BEGIN THEME LAYOUT STYLES -->
+			<%= stylesheet_link_tag  "application", "global/custom.css", "global/layout.css", "global/search.css", media: "all" %>
+			<!-- END THEME LAYOUT STYLES -->
+		<% else %>
+			<!-- BEGIN PAGE GLOBAL STYLES -->
+			<%= stylesheet_link_tag  "application", "global/login-5.css" %>
+			<!-- END PAGE GLOBAL STYLES -->
+		<% end %>
+		<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
+		<%= csrf_meta_tags %>
+	</head>
 
 	<% if user_signed_in? %>
-	<!-- BEGIN THEME LAYOUT STYLES -->
-	<%= stylesheet_link_tag  "application", "global/custom.css", "global/layout.css", "global/search.css", media: "all" %>
-	<!-- END THEME LAYOUT STYLES -->
-	<% else %>
-	<!-- BEGIN PAGE GLOBAL STYLES -->
-	<%= stylesheet_link_tag  "application", "global/login-5.css"  %>
-	<!-- END PAGE GLOBAL STYLES -->
-	<% end %>
-	
-	<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
-	
-	<%= csrf_meta_tags %>
-</head>
+		<!-- <body class="page-container-bg-solid page-header-menu-fixed"> -->
+		<body class="page-container-bg-solid page-boxed">
+			<% unless flash.empty? %>
+	  		<script type="text/javascript">
+      		<% flash.each do |f| %>
+	      		<% type = f[0].to_s.gsub('alert', 'error').gsub('notice', 'info') %>
+	     			toastr['<%= type %>']('<%= f[1] %>');
+      		<% end %>
+	  		</script>
+	 		<% end %>
 
-<% if user_signed_in? %>
-<!-- <body class="page-container-bg-solid page-header-menu-fixed"> -->
-	<body class="page-container-bg-solid page-boxed">
-	 <% unless flash.empty? %>
-	  <script type="text/javascript">
-	      <% flash.each do |f| %>
-	      <% type = f[0].to_s.gsub('alert', 'error').gsub('notice', 'info') %>
-	     	 toastr['<%= type %>']('<%= f[1] %>');
-	      <% end %>
-	  </script>
-	 <% end %>
-	 
-	<!-- BEGIN HEADER -->
-	<div class="page-header">
-		<!-- BEGIN HEADER TOP -->
-		<div class="page-header-top">
-			<div class="container-fluid">
-				<!-- BEGIN LOGO -->
-				<div class="page-logo">
-					<%= link_to root_path do %>
-					  <%= image_tag "logos/logo-default.png", {:class=>"logo-default"} %>
-					<% end %>	
-				</div>
-				<!-- END LOGO -->
-				<!-- BEGIN TOP NAVIGATION MENU -->
-				<a href="javascript:;" class="menu-toggler"></a>
-				<div class="top-menu">
-					<ul class="nav navbar-nav pull-right">
-						<!-- BEGIN NOTIFICATION DROPDOWN -->
-<!-- 						<li class="dropdown dropdown-extended dropdown-notification dropdown-dark" id="header_notification_bar">
-							<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-close-others="true">
-								<i class="fa fa-bell-o"></i>
-								<span class="badge badge-default">7</span>
-							</a>
-							<ul class="dropdown-menu">
-								<li class="external">
-									<h3>Tienes
-										<strong>2 mensaje(s)</strong> pendientes </h3>
-									<a href="#">ver todos</a>
-								</li>
-								<li>
-									<ul class="dropdown-menu-list scroller" style="height: 250px;" data-handle-color="#637283">
+			<!-- BEGIN HEADER -->
+			<div class="page-header">
+				<!-- BEGIN HEADER TOP -->
+				<div class="page-header-top">
+					<div class="container-fluid">
+						<!-- BEGIN LOGO -->
+						<div class="page-logo">
+							<%= link_to root_path do %>
+							  <%= image_tag "logos/logo-default.png", { class: "logo-default" } %>
+							<% end %>
+						</div>
+						<!-- END LOGO -->
+						<!-- BEGIN TOP NAVIGATION MENU -->
+						<label style="margin-top: 25px;font-size: 14px;"> Módulo - <%= usertype(current_user) %><br><small><%= current_user.pointsale_id.present? ? "Punto de venta - #{current_user.pointsale.name}" : "" %></small></label>
+						<a href="javascript:;" class="menu-toggler"></a>
+						<div class="top-menu">
+							<ul class="nav navbar-nav pull-right">
+								<!-- BEGIN USER LOGIN DROPDOWN -->
+								<li class="dropdown dropdown-user dropdown-dark">
+									<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-close-others="true">
+										<!--<img alt="" class="img-circle" src="../assets/layouts/layout3/img/avatar9.jpg"> -->
+										<%= image_tag "avatar.png", { class: "img-circle" } %>
+										<span class="username username-hide-mobile"> <%= current_user.full_name %> </span>
+									</a>
+									<ul class="dropdown-menu dropdown-menu-default">
 										<li>
-											<a href="javascript:;">
-												<span class="time">justo ahora</span>
-												<span class="details">
-													<span class="label label-sm label-icon label-success">
-													<i class="fa fa-plus"></i>
-													</span> Nuevo producto registrado. 
-												</span>
-											</a>
+											<%= link_to pwdchange_path do %> <i class="fa fa-lock"></i> Cambiar contraseña
+											<% end %>
 										</li>
 										<li>
-											<a href="javascript:;">
-												<span class="time">10 mins</span>
-												<span class="details">
-													<span class="label label-sm label-icon label-warning"> <i class="fa fa-bell-o"></i>
-													</span> Cambios en punto de venta. </span>
-											</a>
+											<%= link_to destroy_user_session_path, method: :delete do %> <i class="fa fa-key"></i> Cerrar sesión
+											<% end %>
 										</li>
 									</ul>
 								</li>
 							</ul>
-						</li> -->
-						<!-- END NOTIFICATION DROPDOWN -->
-
-<!-- 						<li class="droddown dropdown-separator">
-							<span class="separator"></span>
-						</li> -->
-						
-						<!-- BEGIN USER LOGIN DROPDOWN -->
-						<li class="dropdown dropdown-user dropdown-dark">
-							<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-close-others="true">
-								<!--<img alt="" class="img-circle" src="../assets/layouts/layout3/img/avatar9.jpg"> -->
-								<%= image_tag "avatar.png", {:class=>"img-circle"} %>
-								<span class="username username-hide-mobile"> <%= current_user.full_name %> </span>
-							</a>
-							<ul class="dropdown-menu dropdown-menu-default">
-								<!-- <li>
-									<a href="page_user_profile_1.html">
-										<i class="icon-user"></i> My Profile </a>
-								</li>
-								<li>
-									<a href="app_calendar.html">
-										<i class="icon-calendar"></i> My Calendar </a>
-								</li>
-								<li>
-									<a href="app_inbox.html">
-										<i class="icon-envelope-open"></i> My Inbox
-										<span class="badge badge-danger"> 3 </span>
-									</a>
-								</li>
-								<li>
-									<a href="app_todo_2.html">
-										<i class="icon-rocket"></i> My Tasks
-										<span class="badge badge-success"> 7 </span>
-									</a>
-								</li>
-								<li class="divider"> </li> -->
-								<li>
-									<%= link_to  pwdchange_path   do %> <i class="fa fa-lock"></i> Cambiar contraseña
-									<% end %>
-								</li>
-								<li>
-									<%= link_to  destroy_user_session_path, :method => :delete  do %> <i class="fa fa-key"></i> Cerrar sesión
-									<% end %>
-								</li>
-								<!-- <li>
-									<a href="page_user_lock_1.html">
-										<i class="icon-lock"></i> Lock Screen </a>
-								</li>
-								<li>
-									<a href="page_user_login_1.html">
-										<i class="icon-key"></i> Log Out </a>
-								</li> -->
-							</ul>
-						</li>
-						<!-- END USER LOGIN DROPDOWN -->
-						
-					</ul>
+						</div>
+					</div>
 				</div>
-				<!-- END TOP NAVIGATION MENU -->
-			</div>
-		</div>
-		<!-- END HEADER TOP -->
-		<!-- BEGIN HEADER MENU -->
-		<div class="page-header-menu">
-			<div class="container-fluid">
-				<!-- BEGIN MEGA MENU -->
-				<!-- DOC: Apply "hor-menu-light" class after the "hor-menu" class below to have a horizontal menu with white background -->
-				<!-- DOC: Remove data-hover="dropdown" and data-close-others="true" attributes below to disable the dropdown opening on mouse hover -->
-				<div class="hor-menu  ">
-					<%= render_navigation( expand_all: true, renderer: :bootstrap3 ) %>
-				</div> 
-				<!-- END MEGA MENU -->
+				<div class="page-header-menu">
+					<div class="container-fluid">
+						<!-- BEGIN MEGA MENU -->
+						<!-- DOC: Apply "hor-menu-light" class after the "hor-menu" class below to have a horizontal menu with white background -->
+						<!-- DOC: Remove data-hover="dropdown" and data-close-others="true" attributes below to disable the dropdown opening on mouse hover -->
+						<div class="hor-menu">
+							<%= render_navigation( expand_all: true, renderer: :bootstrap3 ) %>
+						</div>
+						<!-- END MEGA MENU -->
+					</div>
+				</div>
+				<!-- END HEADER MENU -->
 			</div>
-		</div>
-		<!-- END HEADER MENU -->
-	</div>
-	<!-- END HEADER -->
+			<!-- END HEADER -->
 
-	<%= yield %>
-	<%= render 'layouts/dialog' %>
-	<div id="modal-holder"></div>
-	<!-- BEGIN FOOTER -->
-	
-	<!-- BEGIN INNER FOOTER -->
-	<div class="page-footer">
-		<div class="container-fluid"> <%= APP_CREDITS %> 
-			<!-- <a href="http://themeforest.net/item/metronic-responsive-admin-dashboard-template/4021469?ref=keenthemes" title="Purchase Metronic just for 27$ and get lifetime updates for free" target="_blank">Purchase Metronic!</a> -->
-		</div>
-	</div>
-	<div class="scroll-to-top">
-		<i class="fa fa-arrow-up"></i>
-	</div>
-	<!-- END INNER FOOTER -->
-	<!-- END FOOTER -->
-<% else %>
-	<%= yield %>
-<% end %>
+			<%= yield %>
+			<%= render 'layouts/dialog' %>
+			<div id="modal-holder"></div>
+			<!-- BEGIN FOOTER -->
 
-</body>
+			<!-- BEGIN INNER FOOTER -->
+			<div class="page-footer">
+				<div class="container-fluid"> <%= APP_CREDITS %>
+					<!-- <a href="http://themeforest.net/item/metronic-responsive-admin-dashboard-template/4021469?ref=keenthemes" title="Purchase Metronic just for 27$ and get lifetime updates for free" target="_blank">Purchase Metronic!</a> -->
+				</div>
+			</div>
+			<div class="scroll-to-top">
+				<i class="fa fa-arrow-up"></i>
+			</div>
+			<!-- END INNER FOOTER -->
+			<!-- END FOOTER -->
+		<% else %>
+			<%= yield %>
+		<% end %>
+		</body>
 </html>

+ 5 - 0
app/views/layouts/mailer.html.erb

@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <%= yield %>
+  </body>
+</html>

+ 1 - 0
app/views/layouts/mailer.text.erb

@@ -0,0 +1 @@
+<%= yield %>

+ 10 - 9
app/views/pointsales/_assign_delete_prods.html.erb

@@ -46,8 +46,8 @@
 												<div class="note note-success">
 													<h4>Productos disponibles para asignar al punto de venta</h4>
 													<p> En esta tabla se muestran todos los productos disponibles para asignarse al punto de venta para vender.</p><br>
-													<p> Para hacer una busqueda avanzada utiliza el siguiente formato, nombre del producto :atributo a buscar<br>
-														ejemplo. <strong>blusa :verde</strong> (Solo se puede buscar un atributo, ya sea estilo, talla ó color).
+													<p> Para hacer una búsqueda avanzada utiliza el siguiente formato, nombre del producto :atributo a buscar<br>
+														ejemplo. <strong>blusa :verde</strong> (Sólo se puede buscar un atributo, ya sea estilo, talla ó color).
 													</p>
 												</div>
 											</div>
@@ -60,8 +60,9 @@
 														</th>
 														<th>SKU</th>
 														<th>Producto</th>
-														<th>Linea</th>
-														<th>Sub linea</th>
+														<th>Línea</th>
+														<th>Sub línea</th>
+														<th>Precio de venta</th>
 													  </tr>
 													</thead>
 													<tbody>
@@ -83,8 +84,8 @@
 												<div class="note note-success">
 													<h4>Productos asignados al punto de venta</h4>
 													<p> En esta tabla se muestran todos los productos que se han asignado al punto de venta para vender. </p><br>
-													<p> Para hacer una busqueda avanzada utiliza el siguiente formato, nombre del producto :atributo a buscar<br>
-														ejemplo. <strong>blusa :verde</strong> (Solo se puede buscar un atributo, ya sea estilo, talla ó color).
+													<p> Para hacer una búsqueda avanzada utiliza el siguiente formato, nombre del producto :atributo a buscar<br>
+														ejemplo. <strong>blusa :verde</strong> (Sólo se puede buscar un atributo, ya sea estilo, talla ó color).
 												</div>
 											</div>
 											<div class="col-md-12">
@@ -94,8 +95,8 @@
 														<th class="text-center"><input name="select_all" value="1" id="select-all" type="checkbox" /></th>
 														<th>SKU</th>
 														<th>Producto</th>
-														<th>Linea</th>
-														<th>Sub linea</th>
+														<th>Línea</th>
+														<th>Sub línea</th>
 														<th>Stock</th>
 													  </tr>
 													</thead>
@@ -125,7 +126,7 @@
 	var rows_selected_2 = [];
 	var class_1 = '.table_availables';
 	var class_2 = '.table_prod_pointsale';
-	var columns_1 = [{ "data": "0"}, { "data": "1" }, { "data": "2" }, { "data": "3" }, { "data": "4" }];
+	var columns_1 = [{ "data": "0"}, { "data": "1" }, { "data": "2" }, { "data": "3" }, { "data": "4" }, { "data": "5" }];
 	var columns_2 = [{ "data": "0"}, { "data": "1" }, { "data": "2" }, { "data": "3" }, { "data": "4" }, { "data": "5" }];
 	var order_1 = 2;
 	var order_2 = 2;

+ 36 - 26
app/views/pointsales/_assign_products.html.erb

@@ -6,12 +6,13 @@
 				<tr>
 					<th> Producto </th>
 					<th> Stock inicial </th>
+					<th> Precio de venta </th>
 				</tr>
 			</thead>
 			<tbody>
 				<% @products.each do |product| %>
 					<tr id="product_<%= product.id %>">
-						<td> 
+						<td>
 							<strong><%= product.name %></strong> <br>
 							SKU: <%= product.sku %> <br>
 							<% if product.display_attributes.present? %>
@@ -19,8 +20,14 @@
 							<% end %>
 							<%= product.description if product.description.present? %>
 						</td>
-						<td> 
-    						<input type="number" min="0" class="form-control" value="0" pattern="^[0-9]*[1-9][0-9]*$" title="Stock con el que se agregará el producto al punto de venta">
+						<td>
+  						<input type="number" min="0" class="form-control" id="stock_<%= product.id %>" value="0" pattern="^[0-9]*[1-9][0-9]*$" title="Stock con el que se agregará el producto al punto de venta">
+						</td>
+						<td>
+							<div class="input-group">
+                <span class="input-group-addon"> $ </span>
+                <%= number_field_tag "price_sale", product.price_sale, class: 'form-control input-small', id: "price_" + product.id.to_s, min: 0.01 %>
+              </div>
 						</td>
 					</tr>
 				<% end %>
@@ -30,16 +37,20 @@
 	<div class="form-actions">
 		<div class="row">
 			<div class="col-md-9">
-  				<button type="button" title="Asignar los productos seleccionados al punto de venta" 		class="btn blue" onclick="assignOrDeleteProducts($(this))"> 
-  					<i class="fa fa-long-arrow-right"></i> Asignar productos
+				<button type="button" title="Asignar los productos seleccionados al punto de venta"	class="btn blue" onclick="assignOrDeleteProducts($(this))">
+					<i class="fa fa-long-arrow-right"></i> Asignar productos
 				</button>
 				<button class="btn default" onclick="closeModal()">Cancelar</button>
 			</div>
 		</div>
-	</div>	
+	</div>
 </div>
 
 <script>
+	$(document).ready(function(){
+    App.init();
+  });
+
 	function closeModal() {
 		$('#dialog').modal('toggle');
 	}
@@ -49,26 +60,25 @@
 		var products = [];
 		$('#table_assign_or_delete tbody tr').each(function(row) {
 			var idText = $(this).attr('id');
-    		var product_id = idText.substring(idText.lastIndexOf('_') + 1, idText.length);
-    		var obj = { id: product_id, stock: $(this).find('input').val() };			
-	      	products.push(obj);  
-	    });	
-
-	    $.ajax({
-	      type: "POST",
-	      url: "/pointsales/"+ <%= @pointsale.id %> + "/assign_products_to_pointsale",
-	      dataType: "json",
-	      data: {
-	      	products: JSON.stringify(products) 
-	      },
-	      success: function(xhr, status, error) {
-	      	button.attr('disabled', false);
-	      	toastr["success"]("Productos asignados correctamente.");
-	      	$('#dialog').modal('toggle');
-	      	$(class_1).DataTable().draw(); 
-	      	$(class_2).DataTable().draw();
+  		var product_id = idText.substring(idText.lastIndexOf('_') + 1, idText.length);
+  		var obj = { id: product_id, stock: $("#stock_" + product_id).val(), price: $("#price_" + product_id).val() };
+    	products.push(obj);
+    });
 
-	      }
-	    });	 
+    $.ajax({
+      type: "POST",
+      url: "/pointsales/"+ <%= @pointsale.id %> + "/assign_products_to_pointsale",
+      dataType: "json",
+      data: {
+      	products: JSON.stringify(products)
+      },
+      success: function(xhr, status, error) {
+      	button.attr('disabled', false);
+      	toastr["success"]("Productos asignados correctamente.");
+      	$('#dialog').modal('toggle');
+      	$(class_1).DataTable().draw();
+      	$(class_2).DataTable().draw();
+      }
+    });
 	}
 </script>

+ 42 - 42
app/views/pointsales/_form.html.erb

@@ -1,4 +1,4 @@
-<%= form_for(setup_pointsale(@pointsale), :html => {:class=>"form-horizontal"}) do |f| %>
+<%= form_for(setup_pointsale(@pointsale), html: { class: "form-horizontal" }) do |f| %>
 	<div class="portlet-body form">
 		<% if @pointsale.errors.any? %>
 		<div class="alert alert-danger">
@@ -9,49 +9,49 @@
 			<!-- <div class="profile-sidebar"></div>	-->
 			<h4 class="form-section">Información del punto de venta</h4>
 			<div class="form-group">
-				<%= f.label :name, "Nombre del punto de venta", {:class=>"col-md-3 control-label"} do %> Nombre del punto de venta
+				<%= f.label :name, "Nombre del punto de venta", { class: "col-md-3 col-sm-3 control-label" } do %> Nombre del punto de venta
 					<span class="required">*</span>
 				<% end %>
-				<div class="col-md-9">
-					<%= f.text_field :name, {:class=>"form-control"} %>
+				<div class="col-md-4 col-sm-6">
+					<%= f.text_field :name, { class: "form-control" } %>
 				</div>
 			</div>
 			<div class="form-group">
-				<%= f.label :prefix, "Prefijo", {:class=>"col-md-3 control-label"} do %> Prefijo
+				<%= f.label :prefix, "Prefijo", { class: "col-md-3 col-sm-3 control-label" } do %> Prefijo
 					<span class="required">*</span>
 				<% end %>
-				<div class="col-md-9">
-					<%= f.text_field :prefix, {:class=>"form-control"} %>
+				<div class="col-md-3 col-sm-6">
+					<%= f.text_field :prefix, { class: "form-control input-xsmall", maxlength: 3 } %>
 					<span class="help-block">El prefijo es la abreviación que se utilizará para identificar al punto de venta, debe conformarse de 3 letras.</span>
 				</div>
 			</div>
 			<div class="form-group">
-				<%= f.label :address, "Dirección", {:class=>"col-md-3 control-label"} %>
-				<div class="col-md-9">
-					<%= f.text_field :address, {:class=>"form-control"} %>
+				<%= f.label :address, "Dirección", { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-4 col-sm-6">
+					<%= f.text_field :address, { class: "form-control" } %>
 				</div>
 			</div>
 			<div class="form-group">
-				<%= f.label :haggle_percent, {:class=>"col-md-3 control-label"} do %> Porcentaje de regateo para ventas <% end %>
-				<div class="col-md-2">
-					<%= f.number_field :haggle_percent, {:class=>"form-control" }  %>
+				<%= f.label :haggle_percent, { class: "col-md-3 col-sm-3 control-label" } do %> Porcentaje de regateo para ventas <% end %>
+				<div class="col-md-2 col-sm-6">
+					<%= f.number_field :haggle_percent, { class: "form-control input-xsmall" } %>
 				</div>
 			</div>
 			<div class="form-group">
-				<%= f.label :notes, "Encabezado para el ticket", {:class=>"col-md-3 control-label"} %>
-				<div class="col-md-9">
-					<%= f.text_area :notes, {:class=>"form-control", :rows => 5} %>
+				<%= f.label :notes, "Encabezado para el ticket", { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-4 col-sm-6">
+					<%= f.text_area :notes, { class: "form-control", rows: 5 } %>
 				</div>
 			</div>
 			<div class="form-group">
-				<%= f.label :ticket_footer, "Pie de pagina para ticket", {:class=>"col-md-3 control-label"} %>
-				<div class="col-md-9">
-					<%= f.text_area :ticket_footer, {:class=>"form-control", :rows => 5} %>
+				<%= f.label :ticket_footer, "Pie de pagina para ticket", { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-4 col-sm-6">
+					<%= f.text_area :ticket_footer, { class: "form-control", rows: 5 } %>
 				</div>
 			</div>
 			<div class="form-group">
-				<%= f.label :img_pointsale, "Imagen para el ticket", {:class=>"col-md-3 control-label"} %>
-				<div class="col-md-9">
+				<%= f.label :img_pointsale, "Imagen para el ticket", { class: "col-md-3 col-sm-3 control-label" } %>
+				<div class="col-md-4 col-sm-6">
 					<div class="fileinput fileinput-new" data-provides="fileinput">
 						<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
 							<% if @pointsale.img_pointsale? %>
@@ -65,7 +65,7 @@
 							<span class="btn default btn-file">
 								<span class="fileinput-new"> Seleccione imagen </span>
 								<span class="fileinput-exists"> Cambiar </span>
-								<%= f.file_field :img_pointsale, {:class=>"default"} %>
+								<%= f.file_field :img_pointsale, { class: "default" } %>
 								<%= f.hidden_field :img_pointsale_cache %>
 							</span>
 							<a href="javascript:;" class="btn red fileinput-exists" data-dismiss="fileinput"> Borrar </a>
@@ -77,51 +77,51 @@
 				<h4 class="form-section">Usuario responsable de punto de venta</h4>
 				<%= f.fields_for :users, @pointsale.users do |u| %>
 					<div class="form-group">
-						<%= u.label :first_name, "Nombre", {:class=>"col-md-3 control-label"} do %> Nombre
+						<%= u.label :first_name, "Nombre", { class: "col-md-3 col-sm-3 control-label" } do %> Nombre
 							<span class="required">*</span>
 						<% end %>
-						<div class="col-md-9">
-							<%= u.text_field :first_name, {:class=>"form-control"} %>
+						<div class="col-md-3 col-sm-3">
+							<%= u.text_field :first_name, { class: "form-control" } %>
 						</div>
 					</div>
 					<div class="form-group">
-						<%= u.label :last_name, "Apellidos", {:class=>"col-md-3 control-label"} do %> Apellidos
+						<%= u.label :last_name, "Apellidos", { class: "col-md-3 col-sm-3 control-label" } do %> Apellidos
 							<span class="required">*</span>
 						<% end %>
-						<div class="col-md-9">
-							<%= u.text_field :last_name, {:class=>"form-control"} %>
+						<div class="col-md-3 col-sm-3">
+							<%= u.text_field :last_name, { class: "form-control" } %>
 						</div>
 					</div>
 					<div class="form-group">
-						<%= u.label :email, "Correo", {:class=>"col-md-3 control-label"} do %> Correo electrónico
+						<%= u.label :email, "Correo", { class: "col-md-3 col-sm-3 control-label" } do %> Correo electrónico
 							<span class="required">*</span>
 						<% end %>
-						<div class="col-md-9">
-							<%= u.text_field :email, {:class=>"form-control"} %>
+						<div class="col-md-3 col-sm-3">
+							<%= u.text_field :email, { class: "form-control" } %>
 						</div>
 					</div>
 					<div class="form-group">
-						<%= u.label :userid, "Nombre del punto de venta", {:class=>"col-md-3 control-label"} do %> Usuario
+						<%= u.label :userid, "Nombre del punto de venta", { class: "col-md-3 col-sm-3 control-label" } do %> Usuario
 							<span class="required">*</span>
 						<% end %>
-						<div class="col-md-9">
-							<%= u.text_field :userid, {:class=>"form-control"} %>
+						<div class="col-md-3 col-sm-3">
+							<%= u.text_field :userid, { class: "form-control" } %>
 						</div>
 					</div>
 					<div class="form-group">
-						<%= u.label :password, "Nombre del punto de venta", {:class=>"col-md-3 control-label"} do %> Contraseña
+						<%= u.label :password, "Nombre del punto de venta", { class: "col-md-3 col-sm-3 control-label" } do %> Contraseña
 							<span class="required">*</span>
 						<% end %>
-						<div class="col-md-9">
-							<%= u.password_field :password, {:class=>"form-control"} %>
+						<div class="col-md-3 col-sm-3">
+							<%= u.password_field :password, { class: "form-control" } %>
 						</div>
 					</div>
 					<div class="form-group">
-						<%= u.label :password_confirmation, "Confirmar contraseña", {:class=>"col-md-3 control-label"} do %> Confirmar Contraseña
+						<%= u.label :password_confirmation, "Confirmar contraseña", { class: "col-md-3 col-sm-3 control-label" } do %> Confirmar Contraseña
 							<span class="required">*</span>
 						<% end %>
-						<div class="col-md-9">
-							<%= u.password_field :password_confirmation, {:class=>"form-control"} %>
+						<div class="col-md-3 col-sm-3">
+							<%= u.password_field :password_confirmation, { class: "form-control" } %>
 						</div>
 					</div>
 				<% end %>
@@ -130,8 +130,8 @@
 		<div class="form-actions">
 			<div class="row">
 				<div class="col-md-offset-3 col-md-9">
-					<%= f.submit 'Guardar', {:class=>"btn green"} %>
-					<%= link_to 'Cancelar', pointsales_path(:filter => @filter, :current_page => @current_page), {:class=>"btn default"} %>
+					<%= f.submit 'Guardar', { class: "btn green" } %>
+					<%= link_to 'Cancelar', pointsales_path(filter: @filter, current_page: @current_page), { class: "btn default" } %>
 				</div>
 			</div>
 		</div>

+ 19 - 34
app/views/pointsales/_index.html.erb

@@ -1,43 +1,28 @@
 <% @pointsales.each_with_index do |pointsale, key| %>
-<tr>
+  <tr>
     <td><%= key + 1 %></td>
     <td><%= pointsale.name %></td>
     <td><%= pointsale.prefix %></td>
     <td><%= pointsale.address %></td>
-    <td class="text-center"><% if pointsale.products.count > 0 %>
-            <i class="fa fa-check font-green"></i>
-            <% else %>
-            <i class="fa fa-times font-red"></i>
-        <% end %></td>
-    <td class="text-center">
-        <% if pointsale.total_products(pointsale.id) > 0 %>
-            <i class="fa fa-check font-green"></i>
-            <% else %>
-            <i class="fa fa-times font-red"></i>
-        <% end %></td>
-    <td class="text-center"><% if pointsale.status == "active" %>
-            <i class="fa fa-check font-green"></i>
-            <% else %>
-            <i class="fa fa-times font-red"></i>
-            <% end %></td>
-    <td >
-        <%= link_to edit_pointsale_path(pointsale, :todo => "products"), {:class=>"btn btn-icon-only default", :title=>"Actualizar productos disponibles"} do %>
-             <i class="fa fa-object-group"></i>
+    <td class="text-center"><%= product_count(pointsale.products.count) %></td>
+    <td class="text-center"><%= product_count(pointsale.total_products) %></td>
+    <td class="text-center"><%= pointsale_status(pointsale) %></td>
+    <td>
+      <%= link_to edit_pointsale_path(pointsale, todo: "products"), { class: "btn btn-icon-only default", title: "Actualizar productos disponibles" } do %>
+         <i class="fa fa-object-group"></i>
+      <% end %>
+      <%= link_to edit_pointsale_path(pointsale), { class: "btn btn-icon-only btn-primary", title: "Editar punto de venta" } do %>
+         <i class="fa fa-edit"></i>
+      <% end %>
+      <% if pointsale.active? && pointsale.open_cash_registers.where("open_cash_registers.status = ?", 0).count == 0 %>
+        <%= link_to pointsale_update_status_path(pointsale), class: "btn btn-icon-only default", title: "Desactivar punto de venta", data: { confirm: '¿Está seguro de desactivar el punto de venta?', method: 'post' } do %>
+          <i class="fa fa-toggle-off"></i>
         <% end %>
-        <%= link_to edit_pointsale_path(pointsale), {:class=>"btn btn-icon-only btn-primary", :title=>"Editar punto de venta"} do %>
-             <i class="fa fa-edit"></i>
+      <% elsif pointsale.inactive? %>
+        <%= link_to pointsale_update_status_path(pointsale), class: "btn btn-icon-only green-jungle", title: "Activar punto de venta", data: { confirm: '¿Está seguro de activar el punto de venta?', method: 'post' } do %>
+          <i class="fa fa-toggle-on"></i>
         <% end %>
-        <% if pointsale.active? && pointsale.open_cash_registers.where("open_cash_registers.status = 0").count == 0 %>
-            <%= link_to pointsale_update_status_path(pointsale), :class=>"btn btn-icon-only default", :title=>"Desactivar punto de venta", data: { confirm: '¿Esta seguro de desactivar el punto de venta?', method: 'post'}  do %>
-                <i class="fa fa-toggle-off"></i>
-            <% end %>
-        <% elsif pointsale.inactive? %>
-            <%= link_to pointsale_update_status_path(pointsale), :class=>"btn btn-icon-only green-jungle", :title=>"Activar punto de venta", data: { confirm: '¿Esta seguro de activar el punto de venta?', method: 'post'}  do %>
-                <i class="fa fa-toggle-on"></i>
-            <% end %>
-        <% end %>
-
-
+      <% end %>
     </td>
-</tr>
+  </tr>
 <% end %>

+ 49 - 50
app/views/pointsales/edit.html.erb

@@ -1,62 +1,61 @@
-	<!-- BEGIN CONTAINER -->
-	<div class="page-container">
-		<!-- BEGIN CONTENT -->
-		<div class="page-content-wrapper">
-			<!-- BEGIN CONTENT BODY -->
-			<!-- BEGIN PAGE HEAD-->
-			<div class="page-head">
-				<div class="container-fluid">
-					<!-- BEGIN PAGE TITLE -->
-					<div class="page-title">
-						<h1> Punto de Venta </h1>
-					</div>
-					<!-- END PAGE TITLE -->
+<!-- BEGIN CONTAINER -->
+<div class="page-container">
+	<!-- BEGIN CONTENT -->
+	<div class="page-content-wrapper">
+		<!-- BEGIN CONTENT BODY -->
+		<!-- BEGIN PAGE HEAD-->
+		<div class="page-head">
+			<div class="container-fluid">
+				<!-- BEGIN PAGE TITLE -->
+				<div class="page-title">
+					<h1> Punto de Venta </h1>
 				</div>
+				<!-- END PAGE TITLE -->
 			</div>
-			<!-- END PAGE HEAD-->
-			<!-- BEGIN PAGE CONTENT BODY -->
-			<div class="page-content">
-				<div class="container-fluid">
-					<%= link_to  pointsales_path(:filter => @filter, :current_page => @current_page), {:class=>"btn blue-hoki pull-right margin-bottom-10"} do %> <i class="fa fa-angle-left "></i> Regresar
-					<% end %>
-					<!-- BEGIN PAGE BREADCRUMBS -->
-					<ul class="page-breadcrumb breadcrumb">
-						<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
-					</ul>
-					<!-- END PAGE BREADCRUMBS -->
-					<!-- BEGIN PAGE CONTENT INNER -->
-					<div class="page-content-inner">
-						<div class="row ">
-							<!-- editar punto de venta -->
-							<div class='col-md-12'>
-								<div class="portlet light">
-									<div class="portlet-title">
-										<div class="caption">
-											<i class="fa fa-edit font-blue-sharp"></i>
-											<span class="caption-subject font-blue-sharp bold uppercase">
-												<% if @todo == "products" %>
+		</div>
+		<!-- END PAGE HEAD-->
+		<!-- BEGIN PAGE CONTENT BODY -->
+		<div class="page-content">
+			<div class="container-fluid">
+				<%= link_to pointsales_path(:filter => @filter, :current_page => @current_page), {:class=>"btn blue-hoki pull-right margin-bottom-10"} do %> <i class="fa fa-angle-left "></i> Regresar
+				<% end %>
+				<!-- BEGIN PAGE BREADCRUMBS -->
+				<ul class="page-breadcrumb breadcrumb">
+					<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
+				</ul>
+				<!-- END PAGE BREADCRUMBS -->
+				<!-- BEGIN PAGE CONTENT INNER -->
+				<div class="page-content-inner">
+					<div class="row ">
+						<!-- editar punto de venta -->
+						<div class='col-md-12'>
+							<div class="portlet light">
+								<div class="portlet-title">
+									<div class="caption">
+										<i class="fa fa-edit font-blue-sharp"></i>
+										<span class="caption-subject font-blue-sharp bold uppercase">
+											<% if @todo == "products" %>
 												actualizar productos del punto de venta
-												<% else %>
+											<% else %>
 												EDITAR PUNTO DE VENTA
-												<% end %>
-											</span>
-										</div>
+											<% end %>
+										</span>
 									</div>
-									<% if @todo == "products" %>
+								</div>
+								<% if @todo == "products" %>
 									<%= render 'assign_delete_prods' %>
-									<% else %>
+								<% else %>
 									<%= render 'form' %>
-									<% end %>
-								</div>
-							</div>						
-						</div> 
+								<% end %>
+							</div>
+						</div>
 					</div>
-					<!-- END PAGE CONTENT INNER -->
 				</div>
+				<!-- END PAGE CONTENT INNER -->
 			</div>
-			<!-- END PAGE CONTENT BODY -->
-			<!-- END CONTENT BODY -->
 		</div>
-		<!-- END CONTENT -->
+		<!-- END PAGE CONTENT BODY -->
+		<!-- END CONTENT BODY -->
 	</div>
-	<!-- END CONTAINER -->
+	<!-- END CONTENT -->
+</div>

+ 77 - 78
app/views/pointsales/index.html.erb

@@ -1,87 +1,86 @@
-		<!-- BEGIN CONTAINER -->
-		<div class="page-container">
-			<!-- BEGIN CONTENT -->
-			<div class="page-content-wrapper">
-				<!-- BEGIN CONTENT BODY -->
-				<!-- BEGIN PAGE HEAD-->
-				<div class="page-head">
-					<div class="container-fluid">
-						<!-- BEGIN PAGE TITLE -->
-						<div class="page-title">
-							<h1>Puntos de Ventas </h1>
-						</div>
-						<!-- END PAGE TITLE -->
-					</div>
+<!-- BEGIN CONTAINER -->
+<div class="page-container">
+	<!-- BEGIN CONTENT -->
+	<div class="page-content-wrapper">
+		<!-- BEGIN CONTENT BODY -->
+		<!-- BEGIN PAGE HEAD-->
+		<div class="page-head">
+			<div class="container-fluid">
+				<!-- BEGIN PAGE TITLE -->
+				<div class="page-title">
+					<h1>Puntos de Ventas </h1>
 				</div>
-				<!-- END PAGE HEAD-->
-				<!-- BEGIN PAGE CONTENT BODY -->
-				<div class="page-content">
-					<div class="container-fluid">
-						<!-- BEGIN PAGE BREADCRUMBS -->
-						<ul class="page-breadcrumb breadcrumb">
-							<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
-						</ul>
-						<!-- END PAGE BREADCRUMBS -->
-						<!-- BEGIN PAGE CONTENT INNER -->
-						<div class="page-content-inner">
-							<div id="notice">
-								<% if success %>
-								<div class="alert alert-success">
-									<p><%= success %></p>
-								</div>
-								<% elsif warning %>
-								<div class="alert alert-warning">
-									<p><%= warning %></p>
-								</div>
-								<% end %>
-							 </div>
-							<div class="row">
-								<div class="col-md-12">
-									<div class="portlet light ">
-										<div class="portlet-title">
-											<div class="caption">
-												<i class="fa fa-list "></i>
-												<span class="caption-subject bold uppercase">Lista de Puntos de venta</span>
-											</div>
-											<div class="actions">
-												<% if can? :create, Pointsale %>
-												<%= link_to new_pointsale_path, {:class=>"btn bold green pull-right filtros"} do %> Nuevo punto de venta <i class="fa fa-plus"></i>
-												<% end %>
-												<% end %>
-											</div>
-										</div>
-										<div class="portlet-body">
-											<input type='hidden' name='filter' id='filter' value='<%= @filter %>' >
-											<input type='hidden' name='current_page' id='current_page' value='<%= @current_page %>' >
-											<table class="table table-striped table-bordered table-hover tableadvanced">
-												<thead>
-													<tr>
-														<th>#</th>
-														<th>Nombre</th>
-														<th>Prefijo</th>
-														<th>Direcci&oacute;n</th>
-														<th>Productos<br>disponibles</th>
-														<th>¿Tiene inventario?</th>
-														<th>Status</th>
-														<th>Acciones</th>
-													</tr>
-												</thead>
-												<tbody  class="pointsale-index">
-													<%= render "index" %>
-												</tbody>
-											</table>
-										</div>
+				<!-- END PAGE TITLE -->
+			</div>
+		</div>
+		<!-- END PAGE HEAD-->
+		<!-- BEGIN PAGE CONTENT BODY -->
+		<div class="page-content">
+			<div class="container-fluid">
+				<!-- BEGIN PAGE BREADCRUMBS -->
+				<ul class="page-breadcrumb breadcrumb">
+					<%= render_breadcrumbs :tag => :li, :separator => ' <i class="fa fa-circle"></i> ' %>
+				</ul>
+				<!-- END PAGE BREADCRUMBS -->
+				<!-- BEGIN PAGE CONTENT INNER -->
+				<div class="page-content-inner">
+					<div id="notice">
+						<% if success %>
+						<div class="alert alert-success">
+							<p><%= success %></p>
+						</div>
+						<% elsif warning %>
+						<div class="alert alert-warning">
+							<p><%= warning %></p>
+						</div>
+						<% end %>
+					 </div>
+					<div class="row">
+						<div class="col-md-12">
+							<div class="portlet light ">
+								<div class="portlet-title">
+									<div class="caption">
+										<i class="fa fa-list "></i>
+										<span class="caption-subject bold uppercase">Lista de Puntos de venta</span>
 									</div>
+									<div class="actions">
+										<% if can? :create, Pointsale %>
+											<%= link_to new_pointsale_path, {:class=>"btn bold green pull-right filtros"} do %> Nuevo punto de venta <i class="fa fa-plus"></i><% end %>
+										<% end %>
+									</div>
+								</div>
+								<div class="portlet-body">
+									<input type='hidden' name='filter' id='filter' value='<%= @filter %>' >
+									<input type='hidden' name='current_page' id='current_page' value='<%= @current_page %>' >
+									<table class="table table-striped table-bordered table-hover tableadvanced">
+										<thead>
+											<tr>
+												<th>#</th>
+												<th>Nombre</th>
+												<th>Prefijo</th>
+												<th>Direcci&oacute;n</th>
+												<th>Productos<br>disponibles</th>
+												<th>¿Tiene inventario?</th>
+												<th>Status</th>
+												<th>Acciones</th>
+											</tr>
+										</thead>
+										<tbody  class="pointsale-index">
+											<%= render "index" %>
+										</tbody>
+									</table>
 								</div>
 							</div>
 						</div>
-						<!-- END PAGE CONTENT INNER -->
 					</div>
 				</div>
-				<!-- END PAGE CONTENT BODY -->
-				<!-- END CONTENT BODY -->
+				<!-- END PAGE CONTENT INNER -->
 			</div>
-			<!-- END CONTENT -->	
 		</div>
-		<!-- END CONTAINER -->
-		<div id="form-modal" class="modal fade" tabindex="-1" role="basic" aria-hidden="true"> </div>
+		<!-- END PAGE CONTENT BODY -->
+		<!-- END CONTENT BODY -->
+	</div>
+	<!-- END CONTENT -->
+</div>
+<!-- END CONTAINER -->
+<div id="form-modal" class="modal fade" tabindex="-1" role="basic" aria-hidden="true"> </div>

+ 73 - 59
app/views/pos_configs/_form.html.erb

@@ -1,4 +1,4 @@
-<%= form_for(@pos_config, :html => {:class=>"form-horizontal"}) do |f| %>
+<%= form_for(@pos_config, :html => { class: "form-horizontal" }) do |f| %>
 <div class="portlet-body form">
   <% if @pos_config.errors.any? %>
     <div class="alert alert-danger">
@@ -7,118 +7,124 @@
   <% end %>
   <div class="form-body">
     <div class="row">
-      <div class="col-md-11">
+      <div class="col-md-11 col-sm-12">
         <div class="form-group">
-          <%= f.label :cancel_partial_payment,  {:class=>"col-md-3 control-label"} do %>Días para cancelar abono
+          <%= f.label :cancel_partial_payment, { class: "col-md-3 col-sm-3 control-label" } do %>Días para cancelar abono
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :cancel_partial_payment, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :cancel_partial_payment, { class: "form-control input-xsmall" } %>
           </div>
-        </div>
-        <div class="form-group">
-          <%= f.label :refund_sale,  {:class=>"col-md-3 control-label"} do %>Días para aceptar devolución
+          <%= f.label :refund_sale, { class: "col-md-3 col-sm-3 control-label" } do %>Días para aceptar devolución
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :refund_sale, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :refund_sale, { class: "form-control input-xsmall" } %>
           </div>
         </div>
         <div class="form-group">
-          <%= f.label :days_cancel_sale,  {:class=>"col-md-3 control-label"} do %>Días para cancelar venta
+          <%= f.label :days_cancel_sale, { class: "col-md-3 col-sm-3 control-label" } do %>Días para cancelar venta
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :days_cancel_sale, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :days_cancel_sale, { class: "form-control input-xsmall" } %>
           </div>
-        </div>
-        <div class="form-group">
-          <%= f.label :days_cancel_purchase,  {:class=>"col-md-3 control-label"} do %>Días para cancelar compra
+          <%= f.label :days_cancel_purchase, { class: "col-md-3 col-sm-3 control-label"} do %>Días para cancelar compra
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :days_cancel_purchase, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :days_cancel_purchase, { class: "form-control input-xsmall" } %>
           </div>
         </div>
-
         <div class="form-group">
-          <%= f.label :reserve_sale_percent,  {:class=>"col-md-3 control-label"} do %>Porcentaje para realizar apartado
+          <%= f.label :reserve_sale_percent, { class: "col-md-3 col-sm-3 control-label" } do %>Porcentaje para realizar apartado
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :reserve_sale_percent, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :reserve_sale_percent, { class: "form-control input-xsmall" } %>
           </div>
-        </div>
-        <div class="form-group">
-          <%= f.label :days_cancel_reserved,  {:class=>"col-md-3 control-label"} do %>Días para cancelar apartado
+          <%= f.label :days_cancel_reserved, { class: "col-md-3 col-sm-3 control-label" } do %>Días para cancelar apartado
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :days_cancel_reserved, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :days_cancel_reserved, { class: "form-control input-xsmall" } %>
           </div>
         </div>
-
-
         <div class="form-group">
-          <%= f.label :tax_percent,  {:class=>"col-md-3 control-label"} do %>IVA a aplicar
+          <%= f.label :tax_percent, { class: "col-md-3 col-sm-3 control-label" } do %>IVA a aplicar
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :tax_percent, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :tax_percent, { class: "form-control input-xsmall" } %>
           </div>
-        </div>
-        <div class="form-group">
-          <%= f.label :time_zone,  {:class=>"col-md-3 control-label"} do %>Zona horaria
+          <%= f.label :commission_percent, { class: "col-md-3 col-sm-3 control-label" } do %>Porcentaje por comisión de venta
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.time_zone_select :time_zone, ActiveSupport::TimeZone.us_zones, {}, {:class => 'form-control select2 input-large'} %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :commission_percent, { class: "form-control input-xsmall" } %>
           </div>
         </div>
         <div class="form-group">
-          <%= f.label :gain_margin,  {:class=>"col-md-3 control-label"} do %>Porcentaje de margen de ganancia
+          <%= f.label :gain_margin, { class: "col-md-3 col-sm-3 control-label" } do %>Porcentaje de margen de ganancia
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :gain_margin, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.number_field :gain_margin, { class: "form-control input-xsmall" } %>
+          </div>
+          <%= f.label :enable_haggle, { class: "col-md-3 col-sm-3 control-label" } do %> ¿Permitir regateo en ventas? <span class="required">*</span><% end %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.check_box(:enable_haggle,
+              {
+                class: "make-switch",
+                data: {
+                  on_color: "success",
+                  off_color: "danger",
+                  on_text: "Si",
+                  off_text: "No"
+                }
+              }, "true","false"
+            ) %>
+            <%= f.hidden_field :enable_haggle %>
           </div>
         </div>
         <div class="form-group">
-          <%= f.label :haggle_in_sale_percent,  {:class=>"col-md-3 control-label"} do %>Porcentaje de regateo para ventas
-            <span class="required">*</span>
-          <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :haggle_in_sale_percent, {:class=>"form-control input-large" }  %>
+          <div id="haggle_div" class="<%= 'hidden' unless @pos_config.enable_haggle %>">
+            <%= f.label :haggle_in_sale_percent, { class: "col-md-3 col-sm-3 control-label" } do %>Porcentaje máximo de regateo para ventas
+              <span class="required">*</span>
+            <% end %>
+            <div class="col-md-3 col-sm-2">
+              <%= f.number_field :haggle_in_sale_percent, { class: "form-control input-xsmall" } %>
+            </div>
           </div>
         </div>
         <div class="form-group">
-          <%= f.label :commission_percent,  {:class=>"col-md-3 control-label"} do %>Porcentaje por comisión de venta
+          <%= f.label :time_zone, { class: "col-md-3 col-sm-3 control-label" } do %>Zona horaria
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-9">
-            <%= f.number_field :commission_percent, {:class=>"form-control input-large" }  %>
+          <div class="col-md-1 col-sm-2">
+            <%= f.time_zone_select :time_zone, ActiveSupport::TimeZone.us_zones, {}, {:class => 'form-control select2 input-large' } %>
           </div>
         </div>
         <div class="form-group">
-          <%= f.label :ticket_description,  {:class=>"col-md-3 control-label"} do %>Encabezado para tickets
+          <%= f.label :ticket_description, { class: "col-md-3 col-sm-3 control-label" } do %>Encabezado para tickets
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-7">
-            <%= f.text_area :ticket_description, { :class=>"form-control", :rows => 5} %>
+          <div class="col-md-7 col-sm-6">
+            <%= f.text_area :ticket_description, { class: "form-control", rows: 5 } %>
             <span class="help-block">Si no se especifica un encabezado para cada uno de los puntos de venta, se usará este de manera general.</span>
           </div>
         </div>
         <div class="form-group">
-          <%= f.label :ticket_footer,  {:class=>"col-md-3 control-label"} do %>Pie de página para tickets
+          <%= f.label :ticket_footer, { class: "col-md-3 col-sm-3 control-label" } do %>Pie de página para tickets
             <span class="required">*</span>
           <% end %>
-          <div class="col-md-7">
-            <%= f.text_area :ticket_footer, { :class=>"form-control", :rows => 5} %>
+          <div class="col-md-7 col-sm-6">
+            <%= f.text_area :ticket_footer, { class: "form-control", rows: 5 } %>
           </div>
         </div>
         <div class="form-group">
-          <%= f.label :ticket_img, "Imagen para el ticket", {:class=>"col-md-3 control-label"} %>
-          <div class="col-md-9">
+          <%= f.label :ticket_img, "Imagen para el ticket", { class: "col-md-3 col-sm-3 control-label"} %>
+          <div class="col-md-9 col-sm-3">
             <div class="fileinput fileinput-new" data-provides="fileinput">
               <div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
                 <% if @pos_config.ticket_img? %>
@@ -132,7 +138,7 @@
                 <span class="btn default btn-file">
                   <span class="fileinput-new"> Seleccione imagen </span>
                   <span class="fileinput-exists"> Cambiar </span>
-                  <%= f.file_field :ticket_img, {:class=>"default"} %>
+                  <%= f.file_field :ticket_img, { class: "default"} %>
                   <%= f.hidden_field :ticket_img_cache %>
                 </span>
                 <a href="javascript:;" class="btn red fileinput-exists" data-dismiss="fileinput"> Borrar </a>
@@ -146,8 +152,8 @@
   <div class="form-actions">
     <div class="row">
       <div class="col-md-offset-1 col-md-9">
-        <%= f.submit 'Guardar', {:class=>"btn green"} %>
-        <%= link_to 'Cancelar', root_path, {:class=>"btn default"} %>
+        <%= f.submit 'Guardar', { class: "btn green" } %>
+        <%= link_to 'Cancelar', root_path, { class: "btn default" } %>
       </div>
     </div>
   </div>
@@ -158,4 +164,12 @@
     App.init();
   });
 
+  $('input[name="pos_config[enable_haggle]"]').on('switchChange.bootstrapSwitch', function(event, state) {
+    if (state) {
+      $("#haggle_div").removeClass("hidden");
+    } else {
+      $("#haggle_div").addClass("hidden");
+    }
+    $('input[name="pos_config[enable_haggle]"]').val(state);
+  });
 </script>

+ 2 - 2
app/views/pos_configs/index.html.erb

@@ -31,13 +31,13 @@
                 <div class="portlet-title">
                   <div class="caption">
                     <i class="fa fa-fw fa-cog"></i>
-                    <span class="caption-subject bold uppercase">Parametros generales para los puntos de venta</span>
+                    <span class="caption-subject bold uppercase">Párametros generales para los puntos de venta</span>
                   </div>
                 </div>
                 <%= render 'form' %>
               </div>
             </div>
-          </div>                       
+          </div>
         </div>
         <!-- END PAGE CONTENT INNER -->
       </div>

+ 1 - 1
app/views/pre_sales/_pre_sale.html.erb

@@ -19,7 +19,7 @@
   <td><%= pre_sale.discount %></td>
   <td><%= pre_sale.total %></td>
   <td style="width:5%">
-    <% if pre_sale.haggle == 0 %>
+    <% if @pos_config.enable_haggle? && pre_sale.haggle == 0 %>
       <%= link_to add_sale_haggle_path(pre_sale), :remote => true, :class => "btn btn-icon-only btn-primary hagglebutton", :title=>"Agregar regate" do %>
         <i class="fa fa-tag"></i>
       <% end %>

+ 8 - 10
app/views/product_wastes/index.html.erb

@@ -43,9 +43,8 @@
 										<span class="caption-subject bold uppercase">Lista de mermas</span>
 									</div>
 									<div class="actions">
-										<% if current_user.usertype != 'A' %>
-										<%= link_to new_product_waste_path, {:class=>"btn bold green pull-right"} do %> Nueva Merma de producto <i class="fa fa-plus"></i>
-										<% end %>
+										<% if can? :create, ProductWaste %>
+											<%= link_to new_product_waste_path, {:class=>"btn bold green pull-right"} do %> Nueva Merma de producto <i class="fa fa-plus"></i><% end %>
 										<% end %>
 									</div>
 								</div>
@@ -60,7 +59,7 @@
 												<th>Motivo</th>
 												<th>Registró</th>
 												<th>Fecha</th>
-												<% if current_user.usertype == 'A'%>
+												<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
 													<th>Localización</th>
 												<% end %>
 												<th>Status</th>
@@ -70,7 +69,7 @@
 										<tbody>
 											<% @product_wastes.each_with_index do |product_waste, key| %>
 											<tr>
-												<td><%= key +1 %></td>
+												<td><%= key + 1 %></td>
 												<td><%= product_waste.product.sku %> </td>
 												<td>
 													<%= product_waste.product.name %><br>
@@ -80,19 +79,19 @@
 												<td><%= product_waste.reason %> </td>
 												<td><%= product_waste.user.first_name %> </td>
 												<td><%= l(product_waste.created_at, :format => '%d/%B/%Y') %></td>
-												<% if current_user.usertype == 'A'%>
-													<td> <%= product_waste.pointsale.present? ?  product_waste.pointsale.name : product_waste.warehouse.name %> </td>
+												<% if current_user.usertype == "A" || current_user.usertype == "SS" %>
+													<td> <%= product_waste.pointsale.present? ? product_waste.pointsale.name : product_waste.warehouse.name %> </td>
 												<% end %>
 												<td class="text-center">
 													<% case product_waste.status %>
 													<% when "active"%>
 														<i class="fa fa-check font-green"></i>
 													<% when "inactive"%>
-														<i class="fa fa-close font-red"></i>                         
+														<i class="fa fa-close font-red"></i>
 													<% end %>
 												</td>
 												<td class="text-center">
-													<%= link_to product_waste, method: :delete, :class => "btn btn-icon-only btn-danger", :title => "Eliminar merma", data: { confirm: '¿Esta seguro de eliminar la merma del producto?'}   do %> 
+													<%= link_to product_waste, method: :delete, :class => "btn btn-icon-only btn-danger", :title => "Eliminar merma", data: { confirm: '¿Está seguro de eliminar la merma del producto?' } do %>
 														<i class="fa fa-trash-o"></i>
 													<% end %>
 												</td>
@@ -113,4 +112,3 @@
 	</div>
 	<!-- END CONTENT -->
 </div>
-<!-- END CONTAINER

+ 418 - 442
app/views/products/_form.html.erb

@@ -1,465 +1,441 @@
 <!-- BEGIN FORM-->
-<%= form_for(@product, :html => {:class=>"form-horizontal"}) do |f| %>
-	<div class="portlet-body form" id="products_form">
-		<% if @product.errors.any? %>
-			<div class="alert alert-danger">
-				<strong>Tiene <%= pluralize(@product.errors.count, "error") %> no se puede guardar el producto</strong><br>
-			</div>
-		<% end %>
-		<div class="form-body">
-			<input type="text" class="hidden" value="<%= @product.id %>" id="idproduct">
-			<h4 class="form-section">Información general</h4>
-			<div class="row">
-				<div class="col-md-7">
-					<%= hidden_field_tag :gain_margin, @pos_config.gain_margin %>
-					<%= hidden_field_tag :tax_percent, @pos_config.tax_percent %>
-					<div class="form-group">
-						<%= f.label :sku, {:class=>"col-md-3 control-label"} do %>SKU <span class="required">*</span>
-						<% end %>
-						<div class="col-md-9">
-							<div class="input-icon">
-								<i class="fa fa-tag"></i>
-								<%= f.text_field :sku, {:class=>"form-control input-medium", :readonly => true } %>
-							</div>
-							<span class="help-block">El SKU se genera automaticamente en base a la linea y sublinea seleccionadas. </span>
-						</div>
-					</div>
-					<div class="form-group">
-						<%= f.label :barcode, {:class=>"col-md-3 control-label"} do %> Codigo de barras <span class="required">*</span>
-						<% end %>
-						<div class="col-md-9">
-							<div class="input-icon">
-								<i class="fa fa-barcode"></i>
-								<%= f.text_field :barcode, {:class=>"form-control input-medium", :readonly => true } %>
-							</div>
-							<span class="help-block">Para indicar el codigo de barras, debe de escanearlo. </span>
-						</div>
-					</div>
-					<div class="form-group">
-						<%= f.label :name, "Producto", {:class=>"col-md-3 control-label"} do %>Nombre
-							<span class="required">*</span>
-						<% end %>
-						<div class="col-md-9">
-							<%= f.text_field :name, {:class=>"form-control"} %>
-						</div>
-					</div>
-					<div class="form-group">
-						<%= f.label :description, "Descripción", {:class=>"col-md-3 control-label"} %>
-						<div class="col-md-9">
-							<%= f.text_area :description, {:class=>"form-control"} %>
-						</div>
-					</div>
-					<div class="form-group">
-						<%= f.label :unit_id, "Unidad de medida", {:class=>"col-md-3 control-label"} do %>Unidad de medida <span class="required">*</span>
-						<% end %>
-						<div class="col-md-9">
-							<%= f.collection_select :unit_id, Unit.vigentes, :id, :unit, {:prompt => "Seleccione"}, {:class => "form-control input-medium"}   %>
-						</div>
-					</div>
-				</div>
-				<div class="col-md-5">
-					<div class="form-group">
-						<%= f.label :img_product, "Imagen producto", {:class=>"col-md-5 control-label"} %>
-						<div class="col-md-7">
-							<div class="fileinput fileinput-new" data-provides="fileinput">
-								<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
-									<% if @product.img_product? %>
-										<%= image_tag @product.img_product %>
-									<% else %>
-										<%= image_tag "no-image.png" %>
-									<% end %>
-								</div>
-								<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;"> </div>
-								<div>
-									<span class="btn default btn-file">
-										<span class="fileinput-new"> Seleccione imagen </span>
-										<span class="fileinput-exists"> Cambiar </span>
-										<%= f.file_field :img_product, {:class=>"default"} %>
-										<%= f.hidden_field :img_product_cache %>
-									</span>
-									<a href="javascript:;" class="btn red fileinput-exists" data-dismiss="fileinput"> Borrar </a>
-								</div>
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-			<h4 class="form-section">Información del producto</h4>
-			<div class="row">
-				<div class="form-group ">
-					<%= f.label :inventory, "¿Se maneja inventario de este producto?", {:class=>"col-md-3 control-label"} do %>¿Este producto tendrá inventario?
-						<span class="required">*</span>
-					<% end %>
-					<div class="col-md-9">
-						<%= f.check_box(:inventory,
-							{
-								class: "make-switch",
-								data: {
-									on_color: "success",
-									off_color: "danger",
-									on_text: "Si",
-									off_text: "No"
-								}
-							}, "true","false"
-						) %>
-					</div>
-				</div>
-
-				<div class="form-group">
-					<%
-						@category = nil
-						@subcategory = nil;
-						@prompt = 'Seleccione'
-						@disabled = true
-						if @product.categories[0].present? && @product.categories[0].parent_id == 0
-							@category = @product.categories[0]
-							@prompt = ''
-						elsif @product.categories[0].present?
-							@category = Category.find(@product.categories[0].parent_id)
-							@subcategory = @product.categories[0]
-							@disabled = false
-						end
-					%>
-					<%= label_tag :categorias, "Líneas de producto", {:class=>"col-md-3 control-label"} do %>Líneas de producto
-						<span class="required">*</span>
-					<% end %>
-					<div class="col-md-4">
-							<%= select_tag 'categorias',
-								options_from_collection_for_select(Category.activos_padre, 'id', 'category',
-									:selected => (@category.id unless @category.nil?)),
-									{:include_blank => "Seleccione", :class => 'form-control'} %>
-					</div>
-				</div>
-				<div class="form-group">
-					<%= f.label :category_ids, "Sublinea del producto", {:class=>"col-md-3 control-label"}   %>
-					<div class="col-md-4">
-						<%= f.collection_select(:category_ids, @category.nil? ? {} : Category.where(:parent_id => @category.id), :id, :category , options ={:include_blank => @prompt, :selected => (@subcategory.id unless @subcategory.nil?) }, :class => "form-control", :disabled => @disabled) %>
-						<%= f.hidden_field :category_ids, {:id => 'subcategory_hidden'}%>
-					</div>
-				</div>
-				<div class="form-group">
-					<%= f.label :include_purchase_tax, "¿Incluir IVA en compra?", {:class=>"col-md-3 control-label"} do %> ¿Incluir IVA en compra?
-						<span class="required">*</span>
-					<% end %>
-					<div class="col-md-9">
-						<%= f.check_box(:include_purchase_tax,
-							{
-								class: "make-switch",
-								data: {
-									on_color: "success",
-									off_color: "danger",
-									on_text: "Si",
-									off_text: "No"
-								}
-							}, "1","0"
-						) %>
-					</div>
-				</div>
-				<div class="form-group">
-					<%= f.label :include_sale_tax, "¿Incluir IVA en venta?", {:class=>"col-md-3 control-label"} do %> ¿Incluir IVA en venta?
-						<span class="required">*</span>
-					<% end %>
-					<div class="col-md-9">
-						<%= f.check_box(:include_sale_tax,
-							{
-								class: "make-switch",
-								data: {
-									on_color: "success",
-									off_color: "danger",
-									on_text: "Si",
-									off_text: "No"
-								}
-							}, "1","0"
-						) %>
-					</div>
-				</div>
-				<div class="form-group">
-					<%= f.label :is_in_dollars, "¿Se compra en dolares?", {:class=>"col-md-3 control-label"} do %> ¿Se compra en dolares?
-						<span class="required">*</span>
-					<% end %>
-					<div class="col-md-9">
-						<%= f.check_box(:is_in_dollars,
-							{
-								class: "make-switch",
-								data: {
-									on_color: "success",
-									off_color: "danger",
-									on_text: "Si",
-									off_text: "No"
-								}
-							}, "true","false"
-						) %>
-					</div>
-				</div>
-				<div class="form-group inventory">
-					<%= f.label :price_base_dollars, "Precio de compra neto", {:class=>"col-md-3 control-label"} %>
-					<div class="col-md-3">
-
-						<div class="input-group <%=(@product.persisted? && @product.is_in_dollars?) ? '' : 'hidden' %>" id="price_base_usd_div">
-							<span class="input-group-addon"> $ </span>
-							<%= f.text_field :price_base_dollars, {:class=>"form-control mask_decimal"} %>
-							<span class="input-group-addon"> USD </span>
-						</div>
-
-						<div class="input-group <%=(@product.persisted? && !@product.is_in_dollars?) ? '' : 'hidden' %>" id="price_base_mxn_div">
-							<span class="input-group-addon"> $ </span>
-							<%= f.text_field :price_base, {:class=>"form-control mask_decimal"} %>
-							<span class="input-group-addon"> MXN </span>
-						</div>
-
-					</div>
-				</div>
-				<div class="form-group inventory">
-					<%= f.label :price_sale, "Precio de venta base", {:class=>"col-md-3 control-label"} do %> Precio de venta base
-						<span class="required">*</span>
-					<% end %>
-					<div class="col-md-3">
-						<div class="input-group">
-							<span class="input-group-addon"> $ </span>
-							<%= f.text_field :price_sale, {:class=>"form-control mask_decimal"} %>
-							<span class="input-group-addon"> MXN </span>
-						</div>
-					</div>
-					<div class="col-md-6">
-						<span class="help-block">El precio de venta base será calculado de acuerdo al porcentaje de utilidad especificado, solo en en caso de especificar el precio de compra neto.</span>
-					</div>
-				</div>
-				<div class="form-group">
-					<%= f.label :presentation, "¿El producto tiene variantes?", {:class=>"col-md-3 control-label"} do %>¿El producto tiene variantes?
-						<span class="required">*</span>
-					<% end %>
-					<div class="col-md-9">
-						<%= f.check_box(:presentation,
-							{
-								class: "make-switch",
-								data: {
-									on_color: "success",
-									off_color: "danger",
-									on_text: "Si",
-									off_text: "No"
-								},
-								readonly: @with_presentation
-							}, "true","false"
-						) %>
-					</div>
-				</div>
-			</div>
-			<h4 class="form-section presentaciones">Variantes</h4>
-			<div class="row presentaciones">
-				<% if @product.persisted? %>
-				<div class="col-md-9 col-md-offset-3">
-					<%= render 'products_children' %>
-				</div>
-				<% else %>
-				<div class="col-md-9 col-md-offset-3">
-					<div class="alert alert-warning hidden">
-						Son <strong id="variantes"></strong> variantes del producto.
-					</div>
-				</div>
-				<div class="form-group ">
-					<%= f.label :size_list, "Tallas", {:class=>"col-md-3 control-label"} %>
-					<div class="col-md-9">
-						<%= f.collection_select(:size_list, @product.size_list, :to_s, :to_s, { :include_blank => false }, {:class=>"form-control input-medium", 'data-role'=>'tagsinput', :multiple => true} ) %>
-						<span class="help-block">Ingrese las diferentes tallas, separandolas con coma (,). </span>
-					</div>
-				</div>
-				<div class="form-group ">
-					<%= f.label :color_list, "Colores", {:class=>"col-md-3 control-label"} %>
-					<div class="col-md-9">
-						<%= f.collection_select(:color_list, @product.color_list, :to_s, :to_s, { :include_blank => false }, {:class=>"form-control input-medium", 'data-role'=>'tagsinput', :multiple => true} ) %>
-						<span class="help-block">Ingrese los diferentes colores, separandolos con coma (,). </span>
-					</div>
-				</div>
-				<div class="form-group ">
-					<%= f.label :style_list, "Estilos", {:class=>"col-md-3 control-label"} %>
-					<div class="col-md-9">
-						<%= f.collection_select(:style_list, @product.style_list, :to_s, :to_s, { :include_blank => false }, {:class=>"form-control input-medium", 'data-role'=>'tagsinput', :multiple => true} ) %>
-						<span class="help-block">Ingrese los diferentes estilos, separandolos con coma (,). </span>
-					</div>
-				</div>
-				<%= hidden_field_tag :variants %>
-				<% end %>
-			</div>
-		</div>
-		<div class="form-actions">
-			<div class="row">
-				<div class="col-md-offset-3 col-md-9">
-					<%= f.submit 'Guardar', {:class=>"btn green"} %>
-					<%= link_to 'Cancelar', products_path(:filter => @filter, :current_page => @current_page), {:class=>"btn default"} %>
-				</div>
-			</div>
-		</div>
-	</div>
+<%= form_for(@product, html: { class: "form-horizontal" }) do |f| %>
+  <div class="portlet-body form" id="products_form">
+    <% if @product.errors.any? %>
+      <div class="alert alert-danger">
+        <strong>Tiene <%= pluralize(@product.errors.count, "error") %> no se puede guardar el producto</strong><br>
+      </div>
+    <% end %>
+    <div class="form-body">
+      <input type="text" class="hidden" value="<%= @product.id %>" id="idproduct">
+      <h4 class="form-section">Información general</h4>
+      <div class="row">
+        <div class="col-md-7">
+          <%= hidden_field_tag :gain_margin, @pos_config.gain_margin %>
+          <%= hidden_field_tag :tax_percent, @pos_config.tax_percent %>
+          <div class="form-group">
+            <%= f.label :sku, { class: "col-md-3 col-sm-2 control-label" } do %>SKU <span class="required">*</span>
+            <% end %>
+            <div class="col-md-9 col-sm-4">
+              <div class="input-icon">
+                <i class="fa fa-tag"></i>
+                <%= f.text_field :sku, { class: "form-control input-medium", readonly: true } %>
+              </div>
+              <span class="help-block">El SKU se genera automáticamente en base a la línea y sublínea seleccionadas. </span>
+            </div>
+          </div>
+          <div class="form-group">
+            <%= f.label :barcode, { class: "col-md-3 col-sm-2 control-label" } do %> Código de barras <span class="required">*</span> <% end %>
+            <div class="col-md-9 col-sm-4">
+              <div class="input-icon">
+                <i class="fa fa-barcode"></i>
+                <%= f.text_field :barcode, { class: "form-control input-medium", readonly: true } %>
+              </div>
+              <span class="help-block">Para indicar el código de barras, debe escanearlo. </span>
+            </div>
+          </div>
+          <div class="form-group">
+            <%= f.label :name, "Producto", { class: "col-md-3 col-sm-2 control-label" } do %>Nombre <span class="required">*</span> <% end %>
+            <div class="col-md-9 col-sm-4">
+              <%= f.text_field :name, { class: "form-control input-large" } %>
+            </div>
+          </div>
+          <div class="form-group">
+            <%= f.label :description, "Descripción", { class: "col-md-3 col-sm-2 control-label" } %>
+            <div class="col-md-9 col-sm-4">
+              <%= f.text_area :description, { class: "form-control input-large" } %>
+            </div>
+          </div>
+          <div class="form-group">
+            <%= f.label :unit_id, "Unidad de medida", { class: "col-md-3 col-sm-2 control-label" } do %>Unidad de medida <span class="required">*</span> <% end %>
+            <div class="col-md-9 col-sm-4">
+              <%= f.collection_select :unit_id, Unit.vigentes, :id, :unit, { prompt: "Seleccione" }, { class: "form-control input-medium" } %>
+            </div>
+          </div>
+        </div>
+        <div class="col-md-5">
+          <div class="form-group">
+            <%= f.label :img_product, "Imagen producto", { class: "col-md-5 col-sm-2 control-label" } %>
+            <div class="col-md-7 col-sm-4">
+              <div class="fileinput fileinput-new" data-provides="fileinput">
+                <div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
+                  <% if @product.img_product? %>
+                    <%= image_tag @product.img_product %>
+                  <% else %>
+                    <%= image_tag "no-image.png" %>
+                  <% end %>
+                </div>
+                <div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;"> </div>
+                <div>
+                  <span class="btn default btn-file">
+                    <span class="fileinput-new"> Seleccione imagen </span>
+                    <span class="fileinput-exists"> Cambiar </span>
+                    <%= f.file_field :img_product, { class: "default" } %>
+                    <%= f.hidden_field :img_product_cache %>
+                  </span>
+                  <a href="javascript:;" class="btn red fileinput-exists" data-dismiss="fileinput"> Borrar </a>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <h4 class="form-section">Información del producto</h4>
+      <div class="row">
+        <div class="form-group ">
+          <%= f.label :inventory, "¿Se maneja inventario de este producto?", { class: "col-md-3 col-sm-3 control-label" } do %>¿Este producto tendrá inventario? <span class="required">*</span> <% end %>
+          <div class="col-md-9 col-sm-2">
+            <%= f.check_box(:inventory,
+              {
+                class: "make-switch",
+                data: {
+                  on_color: "success",
+                  off_color: "danger",
+                  on_text: "Si",
+                  off_text: "No"
+                }
+              }, "true","false"
+            ) %>
+          </div>
+        </div>
+        <div class="form-group">
+          <%
+            @category = nil
+            @subcategory = nil;
+            @prompt = 'Seleccione'
+            @disabled = true
+            if @product.categories[0].present? && @product.categories[0].parent_id == 0
+              @category = @product.categories[0]
+              @prompt = ''
+            elsif @product.categories[0].present?
+              @category = Category.find(@product.categories[0].parent_id)
+              @subcategory = @product.categories[0]
+              @disabled = false
+            end
+          %>
+          <%= label_tag :categorias, "Líneas de producto", { class: "col-md-3 col-sm-3 control-label" } do %>Líneas de producto <span class="required">*</span> <% end %>
+          <div class="col-md-4 col-sm-4">
+            <%= select_tag 'categorias', options_from_collection_for_select(Category.activos_padre, 'id', 'category', :selected => (@category.id unless @category.nil?)), { :include_blank => "Seleccione", :class => 'form-control' } %>
+          </div>
+        </div>
+        <div class="form-group">
+          <%= f.label :category_ids, "Sublinea del producto", { class: "col-md-3 col-sm-3 control-label" }   %>
+          <div class="col-md-4 col-sm-4">
+            <%= f.collection_select(:category_ids, @category.nil? ? {} : Category.where(:parent_id => @category.id), :id, :category , options = { :include_blank => @prompt, :selected => (@subcategory.id unless @subcategory.nil?) }, :class => "form-control", :disabled => @disabled) %>
+            <%= f.hidden_field :category_ids, { :id => 'subcategory_hidden' } %>
+          </div>
+        </div>
+        <div class="form-group">
+          <%= f.label :include_purchase_tax, "¿Incluir IVA en compra?", { class: "col-md-3 col-sm-3 control-label" } do %> ¿Incluir IVA en compra? <span class="required">*</span> <% end %>
+          <div class="col-md-9 col-sm-2">
+            <%= f.check_box(:include_purchase_tax,
+              {
+                class: "make-switch",
+                data: {
+                  on_color: "success",
+                  off_color: "danger",
+                  on_text: "Si",
+                  off_text: "No"
+                }
+              }, "1","0"
+            ) %>
+          </div>
+        </div>
+        <div class="form-group">
+          <%= f.label :include_sale_tax, "¿Incluir IVA en venta?", { class: "col-md-3 col-sm-3 control-label" } do %> ¿Incluir IVA en venta? <span class="required">*</span> <% end %>
+          <div class="col-md-9 col-sm-2">
+            <%= f.check_box(:include_sale_tax,
+              {
+                class: "make-switch",
+                data: {
+                  on_color: "success",
+                  off_color: "danger",
+                  on_text: "Si",
+                  off_text: "No"
+                }
+              }, "1","0"
+            ) %>
+          </div>
+        </div>
+        <div class="form-group">
+          <%= f.label :is_in_dollars, "¿Se compra en dólares?", { class: "col-md-3 col-sm-3 control-label" } do %> ¿Se compra en dólares? <span class="required">*</span> <% end %>
+          <div class="col-md-9 col-sm-2">
+            <%= f.check_box(:is_in_dollars,
+              {
+                class: "make-switch",
+                data: {
+                  on_color: "success",
+                  off_color: "danger",
+                  on_text: "Si",
+                  off_text: "No"
+                }
+              }, "true","false"
+            ) %>
+          </div>
+        </div>
+        <div class="form-group inventory">
+          <%= f.label :price_base_dollars, "Precio de compra neto", { class: "col-md-3 col-sm-3 control-label" } %>
+          <div class="col-md-3 col-sm-3">
+            <div class="input-group <%= (@product.persisted? && @product.is_in_dollars?) ? '' : 'hidden' %>" id="price_base_usd_div">
+              <span class="input-group-addon"> $ </span>
+              <%= f.text_field :price_base_dollars, { class: "form-control mask_decimal" } %>
+              <span class="input-group-addon"> USD </span>
+            </div>
+            <div class="input-group <%= (@product.persisted? && !@product.is_in_dollars?) ? '' : 'hidden' %>" id="price_base_mxn_div">
+              <span class="input-group-addon"> $ </span>
+              <%= f.text_field :price_base, { class: "form-control mask_decimal" } %>
+              <span class="input-group-addon"> MXN </span>
+            </div>
+          </div>
+        </div>
+        <div class="form-group inventory">
+          <%= f.label :price_sale, "Precio de venta base", { class: "col-md-3 col-sm-3 control-label" } do %> Precio de venta base
+            <span class="required">*</span>
+          <% end %>
+          <div class="col-md-3 col-sm-3">
+            <div class="input-group">
+              <span class="input-group-addon"> $ </span>
+              <%= f.text_field :price_sale, { class: "form-control mask_decimal" } %>
+              <span class="input-group-addon"> MXN </span>
+            </div>
+          </div>
+          <div class="col-md-6 col-sm-6">
+            <span class="help-block">El precio de venta base será calculado de acuerdo al porcentaje de utilidad especificado, sólo en caso de especificar el precio de compra neto.</span>
+          </div>
+        </div>
+        <div class="form-group">
+          <%= f.label :presentation, "¿El producto tiene variantes?", { class: "col-md-3 col-sm-3 control-label" } do %>¿El producto tiene variantes?
+            <span class="required">*</span>
+          <% end %>
+          <div class="col-md-9 col-sm-2">
+            <%= f.check_box(:presentation,
+              {
+                class: "make-switch",
+                data: {
+                  on_color: "success",
+                  off_color: "danger",
+                  on_text: "Si",
+                  off_text: "No"
+                },
+                readonly: @with_presentation
+              }, "true", "false"
+            ) %>
+          </div>
+        </div>
+      </div>
+      <h4 class="form-section presentaciones">Variantes</h4>
+      <div class="row presentaciones">
+        <% if @product.persisted? %>
+        <div class="col-md-offset-2 col-md-9 col-sm-offset-2 col-sm-9">
+          <%= render 'products_children' %>
+        </div>
+        <% else %>
+        <div class="col-md-9 col-md-offset-3">
+          <div class="alert alert-warning hidden">
+            Son <strong id="variantes"></strong> variantes del producto.
+          </div>
+        </div>
+        <div class="form-group ">
+          <%= f.label :size_list, "Tallas", { class: "col-md-3 control-label" } %>
+          <div class="col-md-9">
+            <%= f.collection_select(:size_list, @product.size_list, :to_s, :to_s, { include_blank: false }, { class: "form-control input-medium", 'data-role'=>'tagsinput', multiple: true }) %>
+            <span class="help-block">Ingrese las diferentes tallas, separándolas con coma (,) </span>
+          </div>
+        </div>
+        <div class="form-group ">
+          <%= f.label :color_list, "Colores", { class: "col-md-3 control-label" } %>
+          <div class="col-md-9">
+            <%= f.collection_select(:color_list, @product.color_list, :to_s, :to_s, { include_blank: false }, { class: "form-control input-medium", 'data-role'=>'tagsinput', multiple: true }) %>
+            <span class="help-block">Ingrese los diferentes colores, separándolos con coma (,) </span>
+          </div>
+        </div>
+        <div class="form-group ">
+          <%= f.label :style_list, "Estilos", { class: "col-md-3 control-label" } %>
+          <div class="col-md-9">
+            <%= f.collection_select(:style_list, @product.style_list, :to_s, :to_s, { include_blank: false }, { class: "form-control input-medium", 'data-role'=>'tagsinput', multiple: true }) %>
+            <span class="help-block">Ingrese los diferentes estilos, separándolos con coma (,) </span>
+          </div>
+        </div>
+        <%= hidden_field_tag :variants %>
+        <% end %>
+      </div>
+    </div>
+    <div class="form-actions">
+      <div class="row">
+        <div class="col-md-offset-3 col-md-9">
+          <%= f.submit 'Guardar', { class: "btn green" } %>
+          <%= link_to 'Cancelar', products_path(filter: @filter, current_page: @current_page), { class: "btn default" } %>
+        </div>
+      </div>
+    </div>
+  </div>
 <% end %>
 <script type="text/javascript">
-	var timeout = null;
-	var regex = /[a,e,i,o,u]/gi;
-	var skuEdit = "";
-
-	$(document).on('page:change', function() {
+  var timeout = null;
+  var regex = /[a,e,i,o,u]/gi;
+  var skuEdit = "";
 
-		App.init();
+  $(document).on('page:change', function() {
+    App.init();
+    $('.fileinput').fileinput();
+    <% if @product.barcode.blank? %>
+      $('body').barcodeListener().on('barcode.valid', function(e, code) {
+        if($('#product_barcode').length > 0) {
+          $('#product_barcode').val(code);
+          validateBarcode(code);
+        }
+      });
+    <% end %>
 
-		$('.fileinput').fileinput();
+    presentaciones();
+    // < % if @product.children.present? %>
+      getVariants();
+    // < % end %>
+    showPriceBaseInput(<%= @product.is_in_dollars? %>);
 
-		<% if @product.barcode.blank? %>
-			$('body').barcodeListener().on('barcode.valid', function(e, code) {
-				if($('#product_barcode').length > 0) {
-					$('#product_barcode').val(code);
-					validateBarcode(code);
-				}
-			});
-		<% end %>
+    $(document).on("cut copy paste",'form#new_product .presentaciones input[type=text]', function(e) {
+      // evitar que se pueda copiar y pegar en los inputs de los tags de variantes
+      e.preventDefault();
+    });
+  });
 
-		presentaciones();
-		getVariants();
-		showPriceBaseInput(<%= @product.is_in_dollars? %>);
+  $('#product_size_list').on('change', function(event) { getVariants(); });
+  $('#product_color_list').on('change', function(event) { getVariants(); });
+  $('#product_style_list').on('change', function(event) { getVariants(); });
 
+  function presentaciones(){
+    if ($('#product_presentation').is(':checked')){
+      $('.presentaciones').removeClass('hidden');
+    } else {
+      $('.presentaciones').addClass('hidden');
+    }
+  }
 
-		$(document).on("cut copy paste",'form#new_product .presentaciones input[type=text]',function(e) {
-			// evitar que se pueda copiar y pegar en los inputs de los tags de variantes
-			e.preventDefault();
-		});
-	});
+  $('#product_presentation').on('switchChange.bootstrapSwitch', function(event, state) {
+    presentaciones();
+  });
 
-	$('#product_size_list').on('change', function(event) { getVariants(); });
-	$('#product_color_list').on('change', function(event) { getVariants(); });
-	$('#product_style_list').on('change', function(event) { getVariants(); });
+  function getVariants(){
+    sizes = $('#product_size_list').tagsinput('items');
+    colors = $('#product_color_list').tagsinput('items');
+    styles = $('#product_style_list').tagsinput('items');
 
-	function presentaciones(){
-		if ($('#product_presentation').is(':checked')){
-			$('.presentaciones').removeClass('hidden');
-		}
-		else{ $('.presentaciones').addClass('hidden'); }
-	}
+    variantes = (sizes.length > 0 ? sizes.length : 1)
+      * (colors.length > 0 ? colors.length : 1 )
+      * (styles.length > 0 ? styles.length : 1);
+    $('#variants').html(variantes);
+    $('.alert-warning').removeClass('hidden');
+    $('#variantes').html(variantes);
+  }
 
-	$('#product_presentation').on('switchChange.bootstrapSwitch', function(event, state) {
-		presentaciones();
-	});
+  $('#categorias').on('change', function() {
+    $('#product_sku').val('');
+    if($('#categorias').val()) {
+      $.ajax({
+        type: "get",
+        url:  '/getcategories/' + $(this).val(),
+        dataType: 'json',
+        success: function(data) {
+          $('#product_category_ids').empty();
+          if(data.length > 0) {
+            $('#product_category_ids').attr('disabled', false);
+            $('#product_category_ids').append("<option selected value='0'>Seleccione</option>")
+          } else {
+            $('#product_category_ids').attr('disabled', true);
+            $('#subcategory_hidden').val($('#categorias').val());
+            $('#product_category_ids').append("<option selected value='" + $('#categorias').val() +"'></option>")
+          }
+          for(i in data){
+            $('#product_category_ids').append("<option value='" + data[i].id +"'>" + data[i].category+ "</option>")
+          }
+          fillSKU();
+        }
+      });
+    }
+  });
 
-	function getVariants(){
-		sizes = $('#product_size_list').tagsinput('items');
-		colors = $('#product_color_list').tagsinput('items');
-		styles = $('#product_style_list').tagsinput('items');
+  $('#product_category_ids').on('change', function() {
+    $('#subcategory_hidden').val($(this).val());
+    fillSKU();
+  });
 
-		variantes = (sizes.length > 0 ? sizes.length : 1)
-			* (colors.length > 0 ? colors.length : 1 )
-				* (styles.length > 0 ? styles.length : 1);
-		$('#variants').html(variantes);
-		$('.alert-warning').removeClass('hidden');
-		$('#variantes').html(variantes);
-	}
+  $('#product_price_base').on('input', function() {
+    getSalePrice($(this));
+  });
 
-	$('#categorias').on('change', function() {
-		$('#product_sku').val('');
-		if($('#categorias').val()) {
-			$.ajax({
-				type: "get",
-				url:  '/getcategories/' + $(this).val(),
-				dataType: 'json',
-				success: function(data) {
-					$('#product_category_ids').empty();
-					if(data.length > 0) {
-						$('#product_category_ids').attr('disabled', false);
-						$('#product_category_ids').append("<option selected value='0'>Seleccione</option>")
-					} else {
-						$('#product_category_ids').attr('disabled', true);
-						$('#subcategory_hidden').val($('#categorias').val());
-						$('#product_category_ids').append("<option selected value='" + $('#categorias').val() +"'></option>")
-					}
-					for(i in data){
-						$('#product_category_ids').append("<option value='" + data[i].id +"'>" + data[i].category+ "</option>")
-					}
-					fillSKU();
-				}
-			});
-		}
-	});
+  $('#product_is_in_dollars').on('switchChange.bootstrapSwitch', function(event, state) {
+    showPriceBaseInput(state);
+  });
 
-	$('#product_category_ids').on('change', function() {
-		$('#subcategory_hidden').val($(this).val());
-		fillSKU();
-	});
+  function getSalePrice(input){
+    clearTimeout(timeout);
+    timeout = setTimeout(function () {
+      var gainMargin = parseFloat($('#gain_margin').val());
+      var purchasePrice = parseFloat(input.val());
+      var gain = (gainMargin / 100) * purchasePrice
+      $('#product_price_sale').val( (purchasePrice + gain).toFixed(2) );
+    }, 500);
+  }
 
-	$('#product_price_base').on('input', function() {
-		getSalePrice($(this));
-	});
 
-	$('#product_is_in_dollars').on('switchChange.bootstrapSwitch', function(event, state) {
-		showPriceBaseInput(state);
-	});
+  function getProductId() {
+    $('#categorias').attr('disabled', true);
+    $.ajax({
+      type: "get",
+      url:  '/get_max_product_id',
+      dataType: 'json',
+      success: function(data) {
+        $('#categorias').attr('disabled', false);
+        var sku = $('#product_sku').val();
+        if(sku.length && !$('#idproduct').val()) {
+          $('#product_sku').val(sku + "-" + data);
+        } else {
+          $('#product_sku').val(sku + "-" + $('#idproduct').val());
+        }
+      },
+    });
+  }
 
-	function getSalePrice(input){
-		clearTimeout(timeout);
-		timeout = setTimeout(function () {
-			var gainMargin = parseFloat($('#gain_margin').val());
-			var purchasePrice = parseFloat(input.val());
-			var gain = (gainMargin / 100) * purchasePrice
-			$('#product_price_sale').val( (purchasePrice + gain).toFixed(2) );
-		}, 500);
-	}
+  function fillSKU() {
+    var sku = $('#product_sku').val();
+    if(sku.length <= 3) {
+      $('#product_sku').val($('#categorias option:selected').text().substring(0,3).toUpperCase());
+      getProductId();
+    }
 
+    sku = $('#product_sku').val();
+    if(sku.length >= 3 && $('#product_category_ids').val() != "0") {
+      var subcategory = $('#product_category_ids option:selected').text();
+      if(subcategory){
+        $('#product_sku').val(sku.substring(0,3) + '-' + subcategory.replace(regex, '').substring(0,3).toUpperCase());
+        getProductId();
+      }
+    }
+  }
 
-	function getProductId() {
-		$('#categorias').attr('disabled', true);
-		$.ajax({
-			type: "get",
-			url:  '/get_max_product_id',
-			dataType: 'json',
-			success: function(data) {
-				$('#categorias').attr('disabled', false);
-				var sku = $('#product_sku').val();
-				if(sku.length && !$('#idproduct').val()) {
-					$('#product_sku').val(sku + "-" + data);
-				} else {
-					$('#product_sku').val(sku + "-" + $('#idproduct').val());
-				}
-			},
-		});
-	}
+  function validateBarcode(barcode) {
+    $.ajax({
+      type: "get",
+      url: '/validate_unique_barcode/' + barcode,
+      dataType: 'script',
+      success: function(data) {
+      }
+    });
+  }
 
-	function fillSKU() {
-		var sku = $('#product_sku').val();
-		if(sku.length <= 3) {
-			$('#product_sku').val($('#categorias option:selected').text().substring(0,3).toUpperCase());
-			getProductId();
-		}
-
-		sku = $('#product_sku').val();
-		if(sku.length >= 3 && $('#product_category_ids').val() != "0") {
-			var subcategory = $('#product_category_ids option:selected').text();
-			if(subcategory){
-				$('#product_sku').val(sku.substring(0,3) + '-' + subcategory.replace(regex, '')
-					.substring(0,3).toUpperCase());
-				getProductId();
-			}
-		}
-	}
-
-	function validateBarcode(barcode) {
-		$.ajax({
-			type: "get",
-			url:  '/validate_unique_barcode/' + barcode,
-			dataType: 'script',
-			success: function(data) {
-			}
-		});
-	}
-
-	function showPriceBaseInput(state) {
-		//true es en dolares, false en pesos
-		if (state) {
-		$('#price_base_usd_div').removeClass('hidden');
-		$('#price_base_mxn_div').addClass('hidden');
-		$('#product_price_base').val('');
-		 <% unless @product.persisted? %>
-			$('#product_price_sale').val('');
-		 <% end %>
-		} else {
-		$('#price_base_mxn_div').removeClass('hidden');
-		$('#price_base_usd_div').addClass('hidden');
-		$('#product_price_base_dollars').val('');
-		}
-	}
+  function showPriceBaseInput(state) {
+    //true es en dolares, false en pesos
+    if (state) {
+    $('#price_base_usd_div').removeClass('hidden');
+    $('#price_base_mxn_div').addClass('hidden');
+    $('#product_price_base').val('');
+     <% unless @product.persisted? %>
+      $('#product_price_sale').val('');
+     <% end %>
+    } else {
+    $('#price_base_mxn_div').removeClass('hidden');
+    $('#price_base_usd_div').addClass('hidden');
+    $('#product_price_base_dollars').val('');
+    }
+  }
 </script>
-

+ 51 - 53
app/views/products/_products_track_dtl.html.erb

@@ -1,53 +1,51 @@
-										<% if !@sales.nil? %>
-										<div class="row">
-											<div class="col-md-12">
-												<div class="col-md-6 col-sm-3 col-xs-6 " >
-													<div class="text-center well" id="container_total_prods" style="margin-bottom: 0px">
-														<div class="font-grey-mint font-sm">Cantidad vendida</div>
-														<div class="uppercase font-hg font-blue-sharp" id="total_prods"> <%= @sales.sum(:quantity) %></div>
-													</div>
-												</div>
-												<div class="col-md-6 col-sm-3 col-xs-6 " >
-													<div class="text-center well" id="container_total_prods" style="margin-bottom: 0px">
-														<div class="font-grey-mint font-sm">Total de ingresos </div>
-														<div class="uppercase font-hg font-blue-sharp" id="total_prods"> <%= number_to_currency(@sales.sum(:total) , precision: 2) %></div>
-													</div>
-												</div>
-											</div>
-										</div>
-										<br>
-										<% end %>
-										<div class="row">
-											<div class="col-md-12">
-												<table class="table table-striped table-bordered table-hover tableadvanced"  >
-													<thead>
-														<tr>
-															<th>Folio Venta</th>
-															<th>Fecha</th>
-															<th>Punto de venta</th>
-															<th>Vendido por </th>
-															<th>Cantidad</th>
-															<th>Precio</th>
-															<th>Descto.</th>
-															<th>Importe</th>
-														</tr>
-													</thead>
-													<tbody>
-													<% if !@sales.nil? %>
-													<% @sales.each_with_index do |sale, key| %>
-														<tr>
-															<td><%= l(sale.sale.date_sale, :format => '%d/%m/%Y') %></td>
-															<td><%= sale.sale.sale_code %> </td>
-															<td><%= sale.sale.get_pointsale.name %></td>
-															<td><%= sale.sale.seller.name %> </td>
-															<td><%= sale.quantity %> </td>
-															<td><%= number_to_currency(sale.amount, precision: 2) %></td>
-															<td><%= number_to_currency(sale.discount, precision: 2) %></td>
-															<td><%= number_to_currency(sale.total, precision: 2) %></td>
-														</tr>
-													<% end %>
-													<% end %>
-													</tbody>
-												</table>
-											</div>
-										</div>
+<% unless @sales.nil? %>
+  <div class="row">
+    <div class="col-md-12">
+      <div class="col-md-6 col-sm-3 col-xs-6 " >
+        <div class="text-center well" id="container_total_prods" style="margin-bottom: 0px">
+          <div class="font-grey-mint font-sm">Cantidad vendida</div>
+          <div class="uppercase font-hg font-blue-sharp" id="total_prods"> <%= @total_quantity.to_i %></div>
+        </div>
+      </div>
+      <div class="col-md-6 col-sm-3 col-xs-6 " >
+        <div class="text-center well" id="container_total_prods" style="margin-bottom: 0px">
+          <div class="font-grey-mint font-sm">Total de ingresos </div>
+          <div class="uppercase font-hg font-blue-sharp" id="total_prods"> <%= number_to_currency(@total_sales, precision: 2) %></div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <br>
+<% end %>
+<div class="row">
+  <div class="col-md-12">
+    <table class="table table-striped table-bordered table-hover tableadvanced">
+      <thead>
+        <tr>
+          <th>Folio Venta</th>
+          <th>Fecha</th>
+          <th>Punto de venta</th>
+          <th>Vendido por </th>
+          <th>Cantidad</th>
+          <th>Precio</th>
+          <th>Descto.</th>
+          <th>Importe</th>
+        </tr>
+      </thead>
+      <tbody>
+        <% @sales.each do |sale, key| %>
+          <tr>
+            <td><%= l(sale.sale.date_sale, format: '%d/%m/%Y') %></td>
+            <td><%= sale.sale.sale_code %> </td>
+            <td><%= sale.sale.get_pointsale.name %></td>
+            <td><%= sale.sale.seller.name %> </td>
+            <td><%= sale.quantity %> </td>
+            <td><%= number_to_currency(sale.amount, precision: 2) %></td>
+            <td><%= number_to_currency(sale.discount, precision: 2) %></td>
+            <td><%= number_to_currency(sale.total, precision: 2) %></td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
+</div>

+ 45 - 0
app/views/products/_products_track_purchases_dtl.html.erb

@@ -0,0 +1,45 @@
+<% unless @purchases.nil? %>
+  <div class="row">
+    <div class="col-md-12">
+      <div class="col-md-6 col-sm-3 col-xs-6 " >
+        <div class="text-center well" id="container_total_prods" style="margin-bottom: 0px">
+          <div class="font-grey-mint font-sm">Cantidad comprada</div>
+          <div class="uppercase font-hg font-blue-sharp" id="total_prods"> <%= @total_quantity_purchases %></div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <br>
+<% end %>
+<div class="row">
+  <div class="col-md-12">
+    <table class="table table-striped table-bordered table-hover tableadvanced">
+      <thead>
+        <tr>
+          <th>Folio compra</th>
+          <th>Fecha</th>
+          <th>Lugar</th>
+          <th>Proveedor</th>
+          <th>Cantidad</th>
+          <th>Capturó</th>
+        </tr>
+      </thead>
+      <tbody>
+        <% @purchases.each_with_index do |purchase_detail, key| %>
+          <tr>
+            <td><%= purchase_detail.purchase.purchase_code %> </td>
+            <td><%= l(purchase_detail.purchase.purchase_date, :format => '%d/%m/%Y') %></td>
+            <% if purchase_detail.purchase.pointsale.present? %>
+             <td><%= purchase_detail.purchase.pointsale.name %></td>
+            <% else %>
+              <td><%= purchase_detail.purchase.warehouse.name %></td>
+            <% end %>
+            <td><%= purchase_detail.purchase.supplier.nick_name %> </td>
+            <td><%= purchase_detail.quantity %> </td>
+            <td><%= purchase_detail.purchase.user.userid %> </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
+</div>

+ 0 - 0
app/views/products/edit.html.erb


Some files were not shown because too many files changed in this diff