_form.html.erb 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <%= form_for(@transfer, :html => {:class=>"form-horizontal", :id=> "transfer_form"}) do |f| %>
  2. <div class="portlet-body form">
  3. <div id="error_explanation"></div>
  4. <div class="row">
  5. <!-- boton para resetear datos -->
  6. <div class="col-md-offset-10 col-md-2">
  7. <button id="reset_pre_transfers" type="button" class="btn btn-warning" <%= @disabled_button ? 'disabled' : '' %> onclick="deletePreTransfers()">Restaurar traspaso</button>
  8. </div>
  9. <div class="col-md-7">
  10. <!-- fecha -->
  11. <div class="form-group">
  12. <%= f.label :transfer_date, "Fecha", {:class=>"col-md-3 control-label"} do %> Fecha
  13. <span class="required">*</span>
  14. <% end %>
  15. <%= f.hidden_field :transfer_date, {:value=>Date.today} %>
  16. <div class="col-sm-6" style="padding-left:0px;padding-right:0px;">
  17. <div class='input-group date' id='datetimepicker1'>
  18. <input type='text' class="form-control" disabled/>
  19. <span class="input-group-addon">
  20. <span class="glyphicon glyphicon-calendar"></span>
  21. </span>
  22. </div>
  23. </div>
  24. </div>
  25. <!-- origen -->
  26. <div class="form-group">
  27. <%= f.label :origin_id, "Punto de venta", {:class=>"col-md-3 control-label"} do %>Origen
  28. <span class="required">*</span>
  29. <% end %>
  30. <div class="input-group col-md-6 select2-bootstrap-prepend">
  31. <%= f.select :origin_id, grouped_options_for_select([
  32. ['Puntos de venta', Pointsale.activos.collect {|p| [ p.name, ('P-' + p.id.to_s) ] }],
  33. ['Almacenes', Warehouse.activos.collect {|w| [ w.name, ('W-' + w.id.to_s)] }]], :selected => @origin_id), {:prompt => "Seleccione"}, { :class => 'form-control select2', :disabled => @disable_origin} %>
  34. <%= f.hidden_field :origin_id, :value => @origin_id, :id => 'origin_id' %>
  35. </div>
  36. </div>
  37. <!-- destino -->
  38. <div class= "form-group">
  39. <%= f.label :destiny_id, "Punto de venta", {:class=>"col-md-3 control-label"} do %>Destino
  40. <span class="required">*</span>
  41. <% end %>
  42. <div class="input-group col-md-6 select2-bootstrap-prepend">
  43. <%= f.select :destiny_id, grouped_options_for_select([
  44. ['Puntos de venta', @destiny_pointsales.collect {|p| [ p.name, ('P-' + p.id.to_s)] }],
  45. ['Almacenes', Warehouse.activos.collect {|w| [ w.name, ('W-' + w.id.to_s)] }]], :selected => @destiny_id), {:prompt => "Seleccione"}, { :class => 'form-control select2', :disabled => @disable_destiny} %>
  46. <%= f.hidden_field :destiny_id, :value => @destiny_id, :id => 'destiny_id' %>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. <!-- agregar productos -->
  52. <h4 class="form-section">Producto(s) a traspasar</h4>
  53. <div class="row">
  54. <div class='col-md-12'>
  55. <div class="form-group">
  56. <label class="col-md-2 control-label" for="typeahead"> Producto
  57. <span class="required">*</span>
  58. </label>
  59. <div class="col-md-4">
  60. <input class="form-control" type="text" id="typeahead" data-option-url="/find_products_from_stock/ID/%QUERY">
  61. </div>
  62. <button id="products_new" disabled class="btn btn-success" type="button" onclick="addRow()"> Agregar <i class="fa fa-plus"></i> </button>
  63. </div>
  64. </div>
  65. </div>
  66. <!-- lista de productos -->
  67. <h4 class="form-section"> </h4>
  68. <div class="portlet-body">
  69. <table class="table table-striped table-bordered table-hover tableadvanced" id="products_table">
  70. <thead>
  71. <tr>
  72. <th width="5%">#</th>
  73. <th width="20%">Imagen</th>
  74. <th width="20%">SKU</th>
  75. <th width="15%">Producto</th>
  76. <th>Stock actual</th>
  77. <th width="20%">Cantidad</th>
  78. <th width="10%">Acciones</th>
  79. </tr>
  80. </thead>
  81. <tbody>
  82. <%= render @pre_transfers %>
  83. </tbody>
  84. </table>
  85. </div>
  86. <!-- acciones del form -->
  87. <div class="form-actions">
  88. <div class="row">
  89. <div class="col-md-9">
  90. <%= f.submit 'Guardar', {:class=>"btn green"} %>
  91. <%= link_to 'Cancelar', transfers_path(:filter => @filter, :current_page => @current_page), {:class=>"btn default"} %>
  92. </div>
  93. </div>
  94. </div>
  95. </div>
  96. <% end %>
  97. <script type="text/javascript">
  98. var selectedProduct;
  99. var timeout = null;
  100. $(document).on("page:change", function() {
  101. App.init();
  102. enumeratePreTransfers();
  103. $('#datetimepicker1').datetimepicker({
  104. icons: {
  105. date: "fa fa-calendar"
  106. },
  107. format: "DD/MM/YYYY",
  108. defaultDate: new Date()
  109. });
  110. });
  111. var bloodhound = new Bloodhound({
  112. datumTokenizer: function (d) {
  113. return Bloodhound.tokenizers.whitespace(d.value);
  114. },
  115. queryTokenizer: Bloodhound.tokenizers.whitespace,
  116. remote: {
  117. url: "/find_from_stock_by_pointsale/ID/" + "%QUERY",
  118. wildcard: '%QUERY',
  119. replace: function(url, uriEncodedQuery) {
  120. origin = $('#origin_id').val();
  121. return url.replace('ID', origin).replace('%QUERY', uriEncodedQuery)
  122. }
  123. }
  124. });
  125. bloodhound.initialize();
  126. $('#typeahead').typeahead(
  127. {
  128. minLength: 3
  129. },
  130. {
  131. displayKey: 'name',
  132. source: bloodhound.ttAdapter(),
  133. limit: Infinity,
  134. templates: {
  135. empty: [
  136. '<div class="empty-message">',
  137. 'No se encontró ningun producto. Favor de verificar',
  138. '</div>'
  139. ].join('\n'),
  140. suggestion: Handlebars.compile(
  141. '<div class="media">' +
  142. '<div class="pull-left">' +
  143. '<div class="media-object">' +
  144. '<img src="{{small_img}}" width="50" height="50"/>' +
  145. '</div>' +
  146. '</div>' +
  147. '<div class="media-body">' +
  148. '<h4 class="media-heading"><strong>{{sku}}</strong> | {{name}}</h4>' +
  149. '<p>{{barcode}}</p>' +
  150. '<p>{{description}}</p>' +
  151. '<p>{{display_attributes}}</p>' +
  152. '</div>' +
  153. '</div>')
  154. }
  155. });
  156. $('body').barcodeListener().on('barcode.valid', function(e, code) {
  157. findProductByBarcode(code);
  158. });
  159. $('#transfer_destiny_id').on('change', function() {
  160. $('#destiny_id').val($(this).val());
  161. });
  162. $('#transfer_origin_id').on('change', function() {
  163. $('#origin_id').val($(this).val());
  164. });
  165. $('#typeahead').bind('typeahead:selected', function(event, datum, name) {
  166. selectedProduct = datum;
  167. $('#products_new').attr('disabled', false);
  168. });
  169. function addRow() {
  170. if(selectedProduct) {
  171. $('#pre_transfer_origin_id').val($('#origin_id').val());
  172. $('#pre_transfer_destiny_id').val($('#transfer_destiny_id').val());
  173. $('#pre_transfer_product_id').val(selectedProduct.id);
  174. $('#pre_transfer_quantity').val(1);
  175. $('#new_pre_transfer').submit();
  176. $('#typeahead').typeahead('val','');
  177. $('#products_new').attr('disabled', true);
  178. }
  179. }
  180. function deleteRow(input) {
  181. var table = $('#products_table').DataTable();
  182. var idText = input.closest('tr').attr('id');
  183. var preTransferId = idText.substring(idText.lastIndexOf('_') + 1, idText.length);
  184. $.ajax({
  185. type: "DELETE",
  186. url: "/pre_transfers/" + preTransferId,
  187. dataType: "json",
  188. data: "",
  189. success: function(xhr, status, error) {
  190. table.row(input.closest('tr')).remove().draw();
  191. }
  192. });
  193. }
  194. function enumeratePreTransfers() {
  195. if($('#reset_pre_transfers').prop("disabled") == false) {
  196. var table = $('#products_table').dataTable();
  197. var counter = 1;
  198. $('#products_table tbody tr').each(function() {
  199. $(this).find('td:eq(0)').html($(this).find('td:eq(0)').html().replace('#', counter));
  200. counter++;
  201. });
  202. }
  203. }
  204. function deletePreTransfers() {
  205. $.ajax({
  206. type: "get",
  207. url: '/delete_pre_transfers',
  208. dataType: 'json',
  209. success: function(xhr, status, error){
  210. $('#products_table').dataTable().fnClearTable();
  211. $("#transfer_destiny_id").select2().select2("val", null);
  212. <% if current_user.usertype == 'A' %>
  213. $("#transfer_origin_id").attr('disabled', false);
  214. $("#transfer_origin_id").select2().select2("val", null);
  215. <% end %>
  216. $("#transfer_destiny_id").attr('disabled', false);
  217. $("#reset_pre_transfers").attr('disabled', true);
  218. }
  219. });
  220. }
  221. function updateQuantity(input) {
  222. if(input.val()) {
  223. clearTimeout(timeout);
  224. timeout = setTimeout(function () {
  225. var idText = input.closest('tr').attr('id');
  226. var preTransferId = idText.substring(idText.lastIndexOf('_') + 1, idText.length);
  227. $.ajax({
  228. type: "PUT",
  229. url: "/pre_transfers/" + preTransferId,
  230. dataType: "json",
  231. data: {pre_transfer: {quantity: input.val()}},
  232. success: function(xhr, status, error) {
  233. },
  234. statusCode: {
  235. 422: function() {
  236. toastr["error"]("Error, El stock es insuficiente.");
  237. }
  238. }
  239. });
  240. }, 700);
  241. }
  242. }
  243. function findProductByBarcode(barcode) {
  244. var origin = $('#origin_id').val();
  245. var destiny = $('#destiny_id').val();
  246. if(origin && destiny) {
  247. $.ajax({
  248. type: "get",
  249. url: '/add_pre_transfer_by_barcode/' + barcode + "/" + origin + "/" + destiny,
  250. dataType: 'script',
  251. success: function(data) {
  252. },
  253. });
  254. } else {
  255. toastr["error"]("Falta seleccionar datos del formulario.");
  256. }
  257. }
  258. </script>