浏览代码

Filter sales by date; remove action column when printing sales table

Jacqueline Maldonado 7 年之前
父节点
当前提交
b27b12454f

+ 21 - 6
app/controllers/sales_controller.rb

@@ -189,28 +189,43 @@ class SalesController < ApplicationController
     if params[:begin_date].present? && params[:end_date].present?
       start_date = DateTime.parse(params[:begin_date])
       end_date = DateTime.parse(params[:end_date])
-      @sales = current_user.usertype == 'A' ? Sale.where(date_sale: start_date..end_date).where.not(saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.where(date_sale: start_date..end_date).where('saletype != 2').order(" created_at DESC ")
+    else
+      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 ")
     respond_to do |format|
       format.js
     end
   end
 
   def find_customer_sales_by_date
-    respond_to do |format|
+    if params[:begin_date].present? && params[:end_date].present?
       start_date = DateTime.parse(params[:begin_date])
       end_date = DateTime.parse(params[:end_date])
-      cliente = params[:cliente]
-      @sales = Sale.where(date_sale: start_date..end_date, customer_id: cliente).where.not(saletype: 2).order(" id DESC ")
+    else
+      start_date = Date.today.beginning_of_month
+      end_date = Date.today.end_of_month
+    end
+    cliente = params[:cliente]
+    @sales = Sale.where(date_sale: start_date..end_date, customer_id: cliente).where.not(saletype: 2).order(" id DESC ")
+
+    respond_to do |format|
       format.js { render action: "find_sales_by_date" }
     end
   end
 
   def find_reserved_sales_by_date
-    respond_to do |format|
+    if params[:begin_date].present? && params[:end_date].present?
       start_date = DateTime.parse(params[:begin_date])
       end_date = DateTime.parse(params[:end_date])
-      @sales = current_user.usertype == 'A' ? Sale.where(date_sale: start_date..end_date, saletype: 2).order(" created_at DESC ") : Pointsale.find(current_user.pointsale_id).sales.where(date_sale: start_date..end_date).where('saletype = 2').order(" created_at DESC ")
+    else
+      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 ")
+
+    respond_to do |format|
       format.js
     end
   end

+ 23 - 0
app/helpers/sales_helper.rb

@@ -1,2 +1,25 @@
 module SalesHelper
+  def sale_type(sale)
+    case sale.saletype
+    when "cash" then
+      "Contado"
+    when "credit" then
+      sale.credit_note.present? ? "Crédito/Vale" : "Crédito"
+    when "reserved" then
+      "Apartado"
+    end
+  end
+
+  def sale_status(sale)
+    case sale.status
+    when "paid" then
+      content_tag(:span, "PAGADA", class: "label label-success")
+    when "cancelled" then
+      content_tag(:span, "CANCELADA", class: "label label-danger")
+    when "parcial" then
+      content_tag(:span, "ABONADA", class: "label label-warning")
+    when "notpaid" then
+      content_tag(:span, "PAGO PENDIENTE", class: "label label-default")
+    end
+  end
 end

+ 2 - 0
app/models/ability.rb

@@ -38,6 +38,8 @@ class Ability
       # Categorias
       can :manage, [Category, Customer, BillingInformation, Expensesconcept, Pointsale, Product, Supplier, Unit, Sale, PosConfig, Purchase, SpecialPrice, ProductWaste, Seller, CashOut, Transfer, Expense, User, Warehouse, Commission, Sellerscommission]
 
+      cannot [:create, :delete, :liquidate_reserve], Sale
+
     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]

+ 29 - 29
app/models/pre_sale.rb

@@ -1,36 +1,36 @@
 class PreSale < ActiveRecord::Base
-	belongs_to :customer
-	belongs_to :user
-	belongs_to :open_cash_register
-	belongs_to :product
-	belongs_to :special_price
+  belongs_to :customer
+  belongs_to :user
+  belongs_to :open_cash_register
+  belongs_to :product
+  belongs_to :special_price
 
-	has_one :cash_register, :through => :open_cash_register
-	has_one :pointsale, :through => :cash_register
-		
-	enum sale_type: [ :credit, :cash, :reserved ]
+  has_one :cash_register, through: :open_cash_register
+  has_one :pointsale, through: :cash_register
 
-	validates :customer_id , :presence => { message: "Debe seleccionar cliente para la venta." }, :on => [:create, :update]
-	validates :open_cash_register_id , :presence => { message: "Debe seleccionar caja registradora." }, :on => [:create, :update]
-	validates :sale_type, presence: { message: "Debe seleccionar tipo de venta." }, :on => [:create, :update]
+  enum sale_type: [:credit, :cash, :reserved]
 
-	# before_save :get_totals
+  validates :customer_id, presence: { message: "Debe seleccionar cliente para la venta." }, on: [:create, :update]
+  validates :open_cash_register_id, presence: { message: "Debe seleccionar caja registradora." }, on: [:create, :update]
+  validates :sale_type, presence: { message: "Debe seleccionar tipo de venta." }, on: [:create, :update]
 
-	def get_totals
-	    special_price = SpecialPrice.find_by(:customer_id => self.customer_id, :product_id => self.product_id)
-	    unless special_price.blank?
-	     	self.special_price_id = special_price.id
-	     	discount_per_unit = special_price.get_unit_discount(self.unit_price)
-	      	self.discount = discount_per_unit * self.quantity
-	    end
+  # before_save :get_totals
 
-	    self.discount += self.haggle
-		self.amount = self.quantity * self.unit_price
-		self.tax = 0.0
-		if self.product.include_sale_tax == 1
-			self.tax = ((PosConfig.first.tax_percent / 100) * self.amount).round(2)
-		end
-		self.total = (self.amount - self.discount) + self.tax
-		return true
-	end
+  def get_totals
+    special_price = SpecialPrice.find_by(customer_id: customer_id, product_id: product_id)
+    unless special_price.blank?
+      self.special_price_id = special_price.id
+      discount_per_unit = special_price.get_unit_discount(unit_price)
+      self.discount = discount_per_unit * quantity
+    end
+
+    self.discount += haggle
+    self.amount = quantity * unit_price
+    self.tax = 0.0
+    if product.include_sale_tax == 1
+      self.tax = ((PosConfig.first.tax_percent / 100) * amount).round(2)
+    end
+    self.total = (amount - discount) + tax
+    return true
+  end
 end

+ 74 - 77
app/models/sale.rb

@@ -1,90 +1,87 @@
 class Sale < ActiveRecord::Base
-	belongs_to :customer
-	belongs_to :user
-	belongs_to :open_cash_register
-	belongs_to :seller
+  belongs_to :customer
+  belongs_to :user
+  belongs_to :open_cash_register
+  belongs_to :seller
 
-	has_many :cash_registers_moves
-	has_many :inventories_moves
-	has_many :sales_details
-  has_many :products, :through => :sales_details
-	has_one :credit
-	has_many :credit_payments, :through => :credit
-	has_one :sales_sellercommission
-	has_many :products_returns
-	has_many :pointsales, :through => :open_cash_register
+  has_many :cash_registers_moves
+  has_many :inventories_moves
+  has_many :sales_details
+  has_many :products, through: :sales_details
+  has_one :credit
+  has_many :credit_payments, through: :credit
+  has_one :sales_sellercommission
+  has_many :products_returns
+  has_many :pointsales, through: :open_cash_register
 
-  	##--- Llevar registro de Actividad del usuario
-	audited
+    ##--- Llevar registro de Actividad del usuario
+  audited
 
-	enum status: [:notpaid, :cancelled, :paid, :parcial, :cancelled_by_expiration]
-	enum saletype: [ :credit, :cash, :reserved ]
+  enum status: [:notpaid, :cancelled, :paid, :parcial, :cancelled_by_expiration]
+  enum saletype: [:credit, :cash, :reserved]
 
-	##--- Validaciones previas de guardar
-	validates :open_cash_register_id, presence: { message: "Se debe seleccionar caja registradora." }, :on => [:create]
-	validates :sale_code, presence: { message: "Se debe seleccionar caja registradora para generar el codigo de venta." }, :on => [:create, :update]
-	validates :customer_id, presence: { message: "Debe seleccionar cliente para la venta." }, :on => [:create, :update]
-	validates :seller_id, presence: { message: "Debe seleccionar vendedor para la venta." }, :on => [:create, :update]
-	validates :saletype, presence: { message: "Debe seleccionar tipo de venta." }, :on => [:create, :update]
+  ##--- Validaciones previas de guardar
+  validates :open_cash_register_id, presence: { message: "Se debe seleccionar caja registradora." }, on: [:create]
+  validates :sale_code, presence: { message: "Se debe seleccionar caja registradora para generar el código de venta." }, on: [:create, :update]
+  validates :customer_id, presence: { message: "Debe seleccionar cliente para la venta." }, on: [:create, :update]
+  validates :seller_id, presence: { message: "Debe seleccionar vendedor para la venta." }, on: [:create, :update]
+  validates :saletype, presence: { message: "Debe seleccionar tipo de venta." }, on: [:create, :update]
 
-	accepts_nested_attributes_for :sales_details
+  accepts_nested_attributes_for :sales_details
 
-	scope :activas, -> { where( "sales.status != 1") }
+  scope :activas, -> { where.not(sales: { status: 1 }) }
 
-	def get_pointsale
-		cash_register = OpenCashRegister.find(self.open_cash_register_id).cash_register
-		pointsale = CashRegister.find(cash_register.id).pointsale
-		return pointsale
-	end
+  def get_pointsale
+    user.pointsale
+  end
 
-	def reserve_is_expired?
-		if self.expiration_date >= Date.today
-			false
-		else
-			true
-		end
-	end
+  def reserve_is_expired?
+    if expiration_date >= Date.today
+      false
+    else
+      true
+    end
+  end
 
-	def self.sales_chart_by_period_of_time(period)
-		all_sales = Array.new
-		if period == 'week'
-	      	beg_period = Date.current.beginning_of_week
-	      	end_period = Date.current.end_of_week
-		elsif period == 'month'
-		    beg_period = Date.current.beginning_of_month
-		    end_period = Date.current.end_of_month
-	    elsif period == 'day'
-		    beg_period = Date.current.beginning_of_day
-		    end_period = Date.current.end_of_day
-		end
-      	Pointsale.activos.each do |pointsale|
-        	obj = {}
-	        obj[:pointsale] = pointsale.name.gsub(" ", "\n")
-	        obj[:total] = pointsale.sales.activas.where(:date_sale => beg_period..end_period).where('sales.status > 1').sum(:total)
-	        all_sales << obj
-      	end
-      	all_sales = all_sales.to_json
-      	return all_sales
-	end
+  def self.sales_chart_by_period_of_time(period)
+    all_sales = Array.new
+    if period == 'week'
+      beg_period = Date.current.beginning_of_week
+      end_period = Date.current.end_of_week
+    elsif period == 'month'
+      beg_period = Date.current.beginning_of_month
+      end_period = Date.current.end_of_month
+    elsif period == 'day'
+      beg_period = Date.current.beginning_of_day
+      end_period = Date.current.end_of_day
+    end
+    Pointsale.activos.each do |pointsale|
+      obj = {}
+      obj[:pointsale] = pointsale.name.gsub(" ", "\n")
+      obj[:total] = pointsale.sales.activas.where(date_sale: beg_period..end_period).where('sales.status > 1').sum(:total)
+      all_sales << obj
+    end
+    all_sales = all_sales.to_json
+    return all_sales
+  end
 
-	def reserve_debt
-		total_in_moves = self.cash_registers_moves.where(:status => 1).sum(:quantity)
-		self.total - total_in_moves
-	end
-
-	def can_be_cancelled?
-		daysToCancel = PosConfig.first.days_cancel_sale
-        if (self.date_sale + daysToCancel.days) >= Date.today && !self.cancelled?
-        	# checar si la venta es de credito y ver si tiene pagos
-        	if self.credit?
-        		has_payments = CreditPayment.where(:credit_id => self.credit.id).any?
-        		has_payments ? (return false) : (return true)
-        	else
-        		return true
-        	end
-        else
-        	return false
-        end
-	end
+  def reserve_debt
+    total_in_moves = cash_registers_moves.where(status: 1).sum(:quantity)
+    total - total_in_moves
+  end
 
+  def can_be_cancelled?(pos_config)
+    daysToCancel = pos_config.days_cancel_sale
+    if (date_sale + daysToCancel.days) >= Date.today && !cancelled?
+      # checar si la venta es de credito y ver si tiene pagos
+      if credit?
+        has_payments = CreditPayment.where(credit_id: credit.id).any?
+        has_payments ? (return false) : (return true)
+      else
+        return true
+      end
+    else
+      return false
+    end
+  end
 end

+ 15 - 37
app/views/sales/_sale.html.erb

@@ -6,49 +6,27 @@
 	<% end %>
 	<td><%= sale.customer.nick_name %> </td>
 	<td><%= sale.seller.name %> </td>
-	<td><%= l(sale.date_sale, :format => '%d/%B/%Y') %></td>
-	<td>
-		<% if sale.saletype == "credit" && sale.credit_note.blank? %>
-		Crédito
-		<% elsif sale.saletype == "credit" && sale.credit_note.present? %>
-		Crédito/vale
-		<% elsif sale.saletype == "cash" %>
-		Contado
-		<% else %>
+	<td><%= l(sale.date_sale, format: '%d/%B/%Y') %></td>
+	<td><%= sale_type(sale) %><br>
 			<!-- Cuando sea apartado, mostrar la fecha de vencimiento -->
-			<%= l(sale.date_sale + @pos_config.days_cancel_reserved.days, :format => '%d/%B/%Y') %>
-		<% end %>
+			<%= l(sale.date_sale + @pos_config.days_cancel_reserved.days, format: '%d/%B/%Y') %>
 	</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>                             
+	<td><%= sale.sales_details.sum(:quantity).to_i %></td>
+	<td><%= sale_status(sale) %></td>
+	<td><%= number_to_currency(sale.total, precision: 2) %>
+		<% if sale.reserved? %>
+			<br><%= number_to_currency(sale.reserve_debt, precision: 2) %>
 		<% end %>
 	</td>
-	<td><%= number_to_currency(sale.total, precision: 2) %></td>
-	<% if sale.reserved?%>
-		<td><%= number_to_currency(sale.reserve_debt, precision: 2) %></td>
-	<% end %>
-	<td class="text-center">
-		<%= link_to sale, {:class=>"btn btn-icon-only default", :title=>"Ver venta"} do %>
+	<td class="text-center hide_c">
+		<%= link_to sale, { class: "btn btn-icon-only default", title: "Ver venta" } do %>
 			<i class="fa fa-search"></i>
 		<% end %>
-
-		<%= link_to print_receipt_path(sale.id, format: 'pdf'), {:class=>"btn btn-icon-only default", :target => "blank"} do %>
+		<%= link_to print_receipt_path(sale.id, format: 'pdf'), { class: "btn btn-icon-only default", target: "blank" } do %>
 			<i class="fa fa-print"></i>
-		<% end %>  
-
-	    <% if current_user.usertype != 'A' %>
-	      <% if sale.can_be_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><% end %>
-	      <% end %>
-	    <% end %>
+		<% end %>
+    <% if (can? :delete, Sale) && sale.can_be_cancelled?(@pos_config) %>
+      <%= 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 %>
   </td>
 </tr>

+ 15 - 15
app/views/sales/_sale_reserved.html.erb

@@ -3,26 +3,26 @@
   <td><%= sale.sale_code %> </td>
   <% if current_user.usertype == 'A' %>
     <td> <%= sale.get_pointsale.name %> </td>
-  <% end %>                         
+  <% end %>
   <td> <%= sale.customer.nick_name %> </td>
   <td> <%= sale.seller.name %> </td>
   <td> <%= l(sale.date_sale, :format => '%d/%m/%Y') %> </td>
   <td> <%= l(sale.expiration_date, :format => '%d/%B/%Y') %> </td>
-  <td> <%= sale.products.count %> </td>
+  <td> <%= sale.sales_details.sum(:quantity) %> </td>
   <td>
-      <% if sale.reserve_is_expired? && !sale.paid? && !sale.cancelled? %> 
-        <span class="label label-warning"> VENCIDO </span> 
+      <% if sale.reserve_is_expired? && !sale.paid? && !sale.cancelled? %>
+        <span class="label label-warning"> VENCIDO </span>
       <% elsif sale.cancelled? %>
-        <span class="label label-danger"> CANCELADO </span> 
+        <span class="label label-danger"> CANCELADO </span>
       <% elsif sale.parcial? %>
-        <span class="label label-success"> VIGENTE </span> 
+        <span class="label label-success"> VIGENTE </span>
       <% elsif sale.paid? %>
-        <span class="label label-success"> PAGADO </span> 
-      <% end %>  
+        <span class="label label-success"> PAGADO </span>
+      <% end %>
   </td>
   <td><%= number_to_currency(sale.total, precision: 2) %></td>
   <td><%= number_to_currency(sale.reserve_debt, precision: 2) %></td>
-  <td>
+  <td class="hide_c">
     <!-- detalle del traspaso -->
     <%= link_to sale, {:class=>"btn btn-icon-only default", :title=>"Ver apartado"} do %>
       <i class="fa fa-search"></i>
@@ -30,7 +30,7 @@
     <!-- reimprimir ticket -->
     <%= link_to print_receipt_path(sale.id, format: 'pdf'), {:class=>"btn btn-icon-only default", :target => "blank"} do %>
       <i class="fa fa-print"></i>
-    <% end %>    
+    <% end %>
     <!-- regresar productos a inventario cuando vencio el apartado -->
     <% if sale.reserve_is_expired? && !sale.cancelled_by_expiration? && !sale.paid? && !sale.cancelled? %>
       <%= link_to sale_return_expired_path(sale), :class=>"btn btn-icon-only btn-info", :title=>"Regresar producto(s) a inventario", data: { confirm: '¿Esta seguro que desea reingresar los productos a inventario?', method: 'post'}  do %>
@@ -38,16 +38,16 @@
       <% end %>
     <% end %>
     <!-- Cancelar apartado -->
-    <% if !sale.reserve_is_expired? && !sale.cancelled? && !sale.paid?%>
-      <%= link_to cancel_reserved_sale_path(sale), :remote => true, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar apartado" do %> 
+    <% if !sale.reserve_is_expired? && !sale.cancelled? && !sale.paid? %>
+      <%= link_to cancel_reserved_sale_path(sale), :remote => true, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar apartado" do %>
         <i class="fa fa-ban"></i>
       <% end %>
     <% end %>
     <!-- liquidar traspaso -->
-    <% if !sale.cancelled_by_expiration? && sale.parcial? %> 
+    <% if (can? :liquidate_reserve, Sale) && !sale.cancelled_by_expiration? && sale.parcial? %>
       <%= link_to sale_liquidate_reserve_path(sale), :remote => true, :class=>"btn btn-icon-only green-dark", :title=>"Liquidar apartado" do %>
         <i class="fa fa-dollar"></i>
-      <% end %>                              
+      <% end %>
     <% end %>
   </td>
-</tr>
+</tr>

+ 142 - 73
app/views/sales/index.html.erb

@@ -43,8 +43,8 @@
                     <span class="caption-subject bold uppercase">Lista de ventas</span>
                   </div>
                   <div class="actions">
-                    <% if current_user.usertype != 'A' %>
-                      <%= link_to new_sale_path, {:class=>"btn bold green pull-right filtros"} do %> Nueva Venta <i class="fa fa-plus"></i>
+                    <% if can? :create, Sale %>
+                      <%= link_to new_sale_path, { class: "btn bold green pull-right filtros" } do %> Nueva Venta <i class="fa fa-plus"></i>
                       <% end %>
                     <% end %>
                   </div>
@@ -53,27 +53,25 @@
                   <div class="form-horizontal" style="margin-bottom:35px">
                     <div class="row">
                       <div class="col-md-11">
-                          <%= hidden_field_tag 'title_for_print' %>
+                        <%= hidden_field_tag 'title_for_print' %>
                         <div class="form-group">
-                          <%= label_tag :begin_date, "Fecha", {:class=>"col-md-1 control-label"} do %> Desde
-                          <% end %>
+                          <%= label_tag :begin_date, "Fecha", { class: "col-md-1 control-label" } do %> Desde <% end %>
                           <div class="col-sm-2" style="padding-left:0px;padding-right:0px;">
-                              <div class='input-group date' id='begin_date'>
-                                  <input id="start" type='text' class="form-control"/>
-                                  <span class="input-group-addon">
-                                      <span class="glyphicon glyphicon-calendar"></span>
-                                  </span>
-                              </div>
+                            <div class='input-group date' id='begin_date'>
+                              <input id="start" type='text' class="form-control" value="<%= l(Date.today.beginning_of_month, format: '%d/%m/%Y') %>" />
+                              <span class="input-group-addon">
+                                <span class="glyphicon glyphicon-calendar"></span>
+                              </span>
+                            </div>
                           </div>
-                          <%= label_tag :end_date, "Fecha", {:class=>"col-md-1 control-label"} do %> Hasta
-                          <% end %>
+                          <%= label_tag :end_date, "Fecha", { class: "col-md-1 control-label" } do %> Hasta <% end %>
                           <div class="col-sm-2" style="padding-left:0px;padding-right:0px;">
-                              <div class='input-group date' id='end_date'>
-                                  <input id="end" type='text' class="form-control"/>
-                                  <span class="input-group-addon">
-                                      <span class="glyphicon glyphicon-calendar"></span>
-                                  </span>
-                              </div>
+                            <div class='input-group date' id='end_date'>
+                              <input id="end" type='text' class="form-control" value="<%= l(Date.today.end_of_month, format: '%d/%m/%Y') %>" />
+                              <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="salesByDate()">
                             <i class="fa fa-search"></i>
@@ -84,7 +82,7 @@
                   </div>
                   <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 tableadvancedprintable" id="sales_table">
+                  <table class="table table-striped table-bordered table-hover" id="sales_table">
                     <thead>
                       <tr>
                         <th>#</th>
@@ -95,11 +93,11 @@
                         <th>Cliente</th>
                         <th>Vendedor</th>
                         <th>Fecha</th>
-                        <th>tipo</th>
+                        <th>Tipo</th>
                         <th>Productos</th>
                         <th>Status</th>
                         <th>Total</th>
-                        <th>Acciones</th>
+                        <th class="hide_c">Acciones</th>
                       </tr>
                     </thead>
                     <tbody>
@@ -112,46 +110,20 @@
                         <% end %>
                         <td><%= sale.customer.nick_name %> </td>
                         <td><%= sale.seller.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
-                          <% elsif sale.saletype == "cash"%>
-                          Contado
-                          <% elsif sale.saletype == "reserved"%>
-                          Apartado
-                          <% end %>
-                        </td>
+                        <td><%= l(sale.date_sale, format: '%d/%m/%Y') %></td>
+                        <td><%= sale_type(sale) %></td>
                         <td><%= sale.sales_details.sum(:quantity).round %></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">PAGO PENDIENTE</span>
-                          <% end %>
-                        </td>
+                        <td><%= sale_status(sale) %></td>
                         <td><%= number_to_currency(sale.total, precision: 2) %></td>
-                        <td>
-                          <%= link_to sale, {:class=>"btn btn-icon-only default filtros", :title=>"Ver venta"} do %>
+                        <td class="text-center hide_c">
+                          <%= link_to sale, { class: "btn btn-icon-only default filtros", title: "Ver venta" } do %>
                             <i class="fa fa-search"></i>
                           <% end %>
-
-                          <%= link_to print_receipt_path(sale.id, format: 'pdf'), {:class=>"btn btn-icon-only default", :target => "blank"} do %>
+                          <%= link_to print_receipt_path(sale.id, format: 'pdf'), { class: "btn btn-icon-only default", target: "blank" } do %>
                             <i class="fa fa-print"></i>
                           <% end %>
-
-                          <% if current_user.usertype != 'A' %>
-                            <% if sale.can_be_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><% end %>
-                            <% end %>
+                          <% if (can? :delete, Sale) && sale.can_be_cancelled?(@pos_config) %>
+                            <%= 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 %>
                         </td>
                       </tr>
@@ -172,45 +144,142 @@
   <!-- END CONTENT -->
 </div>
 <script>
+  var closePrintView = function(e) {
+    if(e.which == 27) {
+      printViewClosed();
+      $('.hide_c').removeClass("hidden");
+    }
+  };
+
+  function printViewClosed() {
+    $("#sales_table").dataTable().fnSetColumnVis('.hide_c', true);
+    $(window).unbind('keyup', closePrintView);
+  }
+
   $(document).on("page:change", function() {
-     App.init();
-     $('#begin_date').datetimepicker({
+    App.init();
+     $('#start').datetimepicker({
       icons: {
         date: "fa fa-calendar"
       },
       format: "DD/MM/YYYY"
-     });
+    });
 
-    $('#end_date').datetimepicker({
+    $('#end').datetimepicker({
       icons: {
         date: "fa fa-calendar"
       },
       format: "DD/MM/YYYY"
     });
 
-    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');
+    var startDate = moment($("#start").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY');
+    var endDate = moment($("#end").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY');
     $('#title_for_print').val('Ventas del ' + startDate + ' al ' + endDate);
+
+
+    $.fn.dataTableExt.oStdClasses.sFilterInput = "form-control input-medium input-inline";
+
+    $.extend(true, $.fn.DataTable.TableTools.classes, {
+      "container": " pull-right margin-bottom-10",
+      "buttons": {
+        "normal": "btn btn-primary margin-right-10",
+        "disabled": "disabled"
+      },
+      "collection": {
+        "container": "DTTT_dropdown dropdown-menu tabletools-dropdown-menu "
+      }
+    });
+
+    var table = $('#sales_table').dataTable({
+      // T = tabletools; l = length changing; f = filtering input; t = table; i = table info; p = pagination
+      "dom": "<'row' <'col-md-12'T>><'row'<'col-md-6 col-sm-12'l><'col-md-6 col-sm-12'f><'col-md-6 col-sm-12'>r><'table-scrollable't><'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>",
+      "tableTools": {
+        "aButtons": [{ // 1
+          "sExtends": "collection",
+          "sButtonText": "Acciones",
+          "aButtons": [ // 2
+            { "sExtends": "print",
+              // "columnDefs": [{
+              //   "targets": 'hide_c',
+              //   "visible": false
+              // }],
+              "sButtonText": "Imprimir",
+              "sInfo": 'Presiona "CTR+P" para imprmir o "ESC" para salir',
+              "sMessage": function() {
+                return "<h2>Lista de ventas desde el " + $("#start").val() + " al " + $("#end").val() + "</h2>";
+              },
+              "fnClick": function(nButton, oConfig) {
+                table.fnSetColumnVis('.hide_c', false);
+                $(window).keyup(closePrintView);
+                this.fnPrint(true, oConfig);
+              }
+            },
+            // { "sExtends": "pdf",
+            //   "sPdfOrientation": "landscape",
+              // "columnDefs": [{
+                // "targets": 'hide_c',
+                // "visible": false
+              // }],
+            //   "sButtonText": "PDF"
+            // }
+          ] // 2
+        }] // 1
+      },
+        "fixedHeader": true,
+        "language": {
+          "aria": {
+            "sortAscending": ": activate to sort column ascending",
+            "sortDescending": ": activate to sort column descending"
+          },
+          "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": [
+            // [0, 'asc']
+        ],
+        "lengthMenu": [
+          [20, 50, 75, 100, -1],
+          [20, 50, 75, 100, "Todos"] // change per page values here
+        ],
+        "pageLength": 20,
+        "bServerSide": false
+    });
   });
 
   function salesByDate() {
-    var start = moment($("#begin_date").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
-    var end = moment($("#end_date").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
+    if ($("#start").val() && $("#end").val()) {
+      var start = moment($("#start").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
+      var end = moment($("#end").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
+    } else {
+      var start = "";
+      var end = "";
+    }
+
     App.blockUI({
-         target: $("#sales_table"),
-         animate: true
+      target: $("#sales_table"),
+      animate: true
     });
+
     $.ajax({
       type: "get",
-      url:  '/find_sales_by_date/' + start + '/' + end,
+      url: '/find_sales_by_date/' + start + '/' + end,
       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($("#start").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY')
+          var endDate = moment($("#end").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY');
+          $('#title_for_print').val('Ventas del ' + startDate + ' al ' + endDate);
+        }, 100);
       }
     });
   }

+ 44 - 40
app/views/sales/sales_reserved.html.erb

@@ -47,27 +47,25 @@
                   <div class="form-horizontal" style="margin-bottom:35px">
                     <div class="row">
                       <div class="col-md-11">
-                          <%= hidden_field_tag 'title_for_print' %>
+                        <%= hidden_field_tag 'title_for_print' %>
                         <div class="form-group">
-                          <%= label_tag :begin_date, "Fecha", {:class=>"col-md-1 control-label"} do %> Desde
-                          <% end %>
+                          <%= label_tag :begin_date, "Fecha", { class: "col-md-1 control-label" } do %> Desde<% end %>
                           <div class="col-sm-2" style="padding-left:0px;padding-right:0px;">
-                              <div class='input-group date' id='begin_date'>
-                                  <input id="start" type='text' class="form-control"/>
-                                  <span class="input-group-addon">
-                                      <span class="glyphicon glyphicon-calendar"></span>
-                                  </span>
-                              </div>
+                            <div class='input-group date' id='begin_date'>
+                              <input id="start" type='text' class="form-control" value="<%= l(Date.today.beginning_of_month, format: '%d/%m/%Y') %>" />
+                              <span class="input-group-addon">
+                                <span class="glyphicon glyphicon-calendar"></span>
+                              </span>
+                            </div>
                           </div>
-                          <%= label_tag :end_date, "Fecha", {:class=>"col-md-1 control-label"} do %> Hasta
-                          <% end %>
+                          <%= label_tag :end_date, "Fecha", { class: "col-md-1 control-label" } do %> Hasta<% end %>
                           <div class="col-sm-2" style="padding-left:0px;padding-right:0px;">
-                              <div class='input-group date' id='end_date'>
-                                  <input id="end" type='text' class="form-control"/>
-                                  <span class="input-group-addon">
-                                      <span class="glyphicon glyphicon-calendar"></span>
-                                  </span>
-                              </div>
+                            <div class='input-group date' id='end_date'>
+                              <input id="end" type='text' class="form-control" value="<%= l(Date.today.end_of_month, format: '%d/%m/%Y') %>" />
+                              <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="salesByDate()">
                             <i class="fa fa-search"></i>
@@ -78,7 +76,7 @@
                   </div>
                   <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 tableadvancedprintable" id="sales_table">
+                  <table class="table table-striped table-bordered table-hover tableadvancedprintable" id="reserved_sales_table">
                     <thead>
                       <tr>
                         <th>#</th>
@@ -94,7 +92,7 @@
                         <th>Status</th>
                         <th>Total</th>
                         <th>Adeudo</th>
-                        <th>Acciones</th>
+                        <th class="hide_c">Acciones</th>
                       </tr>
                     </thead>
                     <tbody>
@@ -109,7 +107,7 @@
                         <td> <%= sale.seller.name %> </td>
                         <td> <%= l(sale.date_sale, :format => '%d/%m/%Y') %> </td>
                         <td> <%= l(sale.expiration_date, :format => '%d/%B/%Y') %> </td>
-                        <td> <%= sale.products.count %> </td>
+                        <td> <%= sale.sales_details.sum(:quantity) %> </td>
                         <td>
                             <% if sale.reserve_is_expired? && !sale.paid? && !sale.cancelled? %>
                               <span class="label label-warning"> VENCIDO </span>
@@ -123,26 +121,26 @@
                         </td>
                         <td><%= number_to_currency(sale.total, precision: 2) %></td>
                         <td><%= number_to_currency(sale.reserve_debt, precision: 2) %></td>
-                        <td>
+                        <td class="hide_c">
                           <!-- detalle del traspaso -->
-                          <%= link_to sale, {:class=>"btn btn-icon-only default filtros", :title=>"Ver apartado"} do %>
+                          <%= link_to sale, { class: "btn btn-icon-only default filtros", title: "Ver apartado" } do %>
                             <i class="fa fa-search"></i>
                           <% end %>
                           <!-- regresar productos a inventario cuando vencio el apartado -->
                           <% if sale.reserve_is_expired? && !sale.cancelled_by_expiration? && !sale.paid?&& !sale.cancelled? %>
-                            <%= link_to sale_return_expired_path(sale), :class=>"btn btn-icon-only btn-info", :title=>"Regresar producto(s) a inventario", data: { confirm: '¿Esta seguro que desea reingresar los productos a inventario?', method: 'post'}  do %>
+                            <%= link_to sale_return_expired_path(sale), class: "btn btn-icon-only btn-info", title: "Regresar producto(s) a inventario", data: { confirm: '¿Está seguro que desea reingresar los productos a inventario?', method: 'post' } do %>
                                 <i class="fa fa-reply"></i>
                             <% end %>
                           <% end %>
                           <!-- Cancelar apartado -->
                           <% if !sale.reserve_is_expired? && !sale.cancelled? && !sale.paid?%>
-                            <%= link_to cancel_reserved_sale_path(sale), :remote => true, :class => "btn btn-icon-only btn-danger", :title=>"Cancelar apartado" do %>
+                            <%= link_to cancel_reserved_sale_path(sale), :remote => true, :class => "btn btn-icon-only btn-danger", title: "Cancelar apartado" do %>
                               <i class="fa fa-ban"></i>
                             <% end %>
                           <% end %>
                           <!-- liquidar traspaso -->
-                          <% if !sale.cancelled_by_expiration? && sale.parcial? %>
-                            <%= link_to sale_liquidate_reserve_path(sale), :remote => true, :class=>"btn btn-icon-only green-dark", :title=>"Liquidar apartado" do %>
+                          <% if (can? :liquidate_reserve, Sale) && !sale.cancelled_by_expiration? && sale.parcial? %>
+                            <%= link_to sale_liquidate_reserve_path(sale), :remote => true, class: "btn btn-icon-only green-dark", title: "Liquidar apartado" do %>
                               <i class="fa fa-dollar"></i>
                             <% end %>
                           <% end %>
@@ -167,43 +165,49 @@
 <script>
   $(document).on("page:change", function() {
      App.init();
-     $('#begin_date').datetimepicker({
+     $('#start').datetimepicker({
       icons: {
         date: "fa fa-calendar"
       },
       format: "DD/MM/YYYY"
     });
 
-    $('#end_date').datetimepicker({
+    $('#end').datetimepicker({
       icons: {
         date: "fa fa-calendar"
       },
       format: "DD/MM/YYYY"
     });
 
-    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');
+    var startDate = moment($("#start").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY')
+    var endDate = moment($("#end").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY');
     $('#title_for_print').val('Ventas del ' + startDate + ' al ' + endDate);
   });
 
   function salesByDate() {
-    var start = moment($("#begin_date").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
-    var end = moment($("#end_date").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
+    if ($("#start").val() && $("#end").val()) {
+      var start = moment($("#start").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
+      var end = moment($("#end").data("date"), "DD-MM-YYYY").format('YYYY-MM-DD HH:mm:ss');
+    } else {
+      var start = "";
+      var end = "";
+    }
     App.blockUI({
-         target: $("#sales_table"),
-         animate: true
+       target: $("#reserved_sales_table"),
+       animate: true
     });
+
     $.ajax({
       type: "get",
       url:  '/find_reserved_sales_by_date/' + start + '/' + end,
       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('Apartados del ' + startDate + ' al ' + endDate);
-          }, 100);
+        window.setTimeout(function() {
+          App.unblockUI($("#reserved_sales_table"));
+          var startDate = moment($("#start").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY')
+          var endDate = moment($("#end").data("date"), "DD-MM-YYYY").format('DD/MM/YYYY');
+          $('#title_for_print').val('Apartados del ' + startDate + ' al ' + endDate);
+        }, 100);
       }
     });
   }