From 87906989a3e30fb1ce0e59ad8e66a694394001e7 Mon Sep 17 00:00:00 2001 From: yarzar_code Date: Fri, 21 Aug 2020 14:53:15 +0630 Subject: [PATCH] added customer report --- README.md | 3 + .../reports/customer_controller.rb | 58 ++++ app/models/sale.rb | 30 ++ app/views/layouts/_left_sidebar.html.erb | 3 + .../_shift_sale_report_filter.html.erb | 144 +++++++++ app/views/reports/customer/index.html.erb | 286 ++++++++++++++++++ app/views/reports/customer/index.xls.erb | 165 ++++++++++ config/routes.rb | 1 + 8 files changed, 690 insertions(+) create mode 100644 app/controllers/reports/customer_controller.rb create mode 100755 app/views/reports/customer/_shift_sale_report_filter.html.erb create mode 100644 app/views/reports/customer/index.html.erb create mode 100644 app/views/reports/customer/index.xls.erb diff --git a/README.md b/README.md index 63ba995a..981a0335 100755 --- a/README.md +++ b/README.md @@ -287,6 +287,9 @@ settings/lookups => {type:show_total_before_tax, name:Show Total Before Tax, val For Using Staff Meal settings/lookups => { type:customer_type, name: Staff, value:Staff } +For Membership Type +settings/lookups => { type:membership_type, name: Timecity staff, value:8 } + - ToDo list 1. Migration diff --git a/app/controllers/reports/customer_controller.rb b/app/controllers/reports/customer_controller.rb new file mode 100644 index 00000000..b623d1e0 --- /dev/null +++ b/app/controllers/reports/customer_controller.rb @@ -0,0 +1,58 @@ +class Reports::CustomerController < BaseReportController + authorize_resource :class => false + def index + @membership_type = Lookup.where(lookup_type: 'membership_type') + from, to = get_date_range_from_params + customer_filter = params[:customer] + + @shift_sale_range = '' + + @shift = '' + if params[:shift_name].to_i != 0 + + @shift_sale_range = Sale.get_by_shift_sale_by_item(from,to,Sale::SALE_STATUS_COMPLETED) + + @shift_sale = ShiftSale.find(params[:shift_name]) + if to.blank? + @shift = ShiftSale.where('shift_started_at = ? and shift_closed_at is NULL ',@shift_sale.shift_started_at) + else + if @shift_sale.shift_closed_at.blank? + @shift = ShiftSale.where('shift_started_at = ? and shift_closed_at is NULL',@shift_sale.shift_started_at) + else + @shift = ShiftSale.where('shift_started_at = ? and shift_closed_at = ? ',@shift_sale.shift_started_at, @shift_sale.shift_closed_at) + end + end + end + + @lookup = Lookup.find_by_lookup_type('reprint_receipt') + if @lookup.nil? + @lookup = Lookup.create_reprint_receipt_lookup + end + if params[:membership_type] == "0" + membership_type = '' + else + membership_type = params[:membership_type] + end + @sale_data = Sale.get_shift_sales_by_customer(@shift_sale_range, @shift, from, to, membership_type, customer_filter) + @sale_taxes = Sale.get_separate_tax(@shift_sale_range, @shift, from, to, nil) + @tax_profiles = TaxProfile.group('name').order('order_by asc') #.limit(2) + + @from = from + @to = to + # get printer info + @print_settings = PrintSetting.get_precision_delimiter() + if @shift.present? + @shift.each do |sh| + @shift_from = sh.shift_started_at.nil? ? '-' : sh.shift_started_at.utc.getlocal.strftime("%e %b %I:%M%p") + @shift_to = sh.shift_closed_at.nil? ? '-' : sh.shift_closed_at.utc.getlocal.strftime("%e %b %I:%M%p") + @shift_data = sh + end + end + + respond_to do |format| + format.html + format.xls + end + end + + end diff --git a/app/models/sale.rb b/app/models/sale.rb index d0b9c90a..247ef00c 100644 --- a/app/models/sale.rb +++ b/app/models/sale.rb @@ -1214,6 +1214,36 @@ def self.get_shift_sales_by_receipt_no(shift_sale_range, shift, from, to, paymen return query end +def self.get_shift_sales_by_customer(shift_sale_range, shift, from, to, membership_type, customer_filter) + ## => left join -> show all sales although no orders + query = Sale.includes(:sale_items).select("sales.*, sale_payments.*") + .select("customers.customer_id, customers.name as customer_name,customers.membership_type as membership_type, dining_facilities.name, dining_facilities.type") + .joins("INNER JOIN sale_payments ON sale_payments.sale_id = sales.sale_id") + .joins("INNER JOIN bookings ON bookings.sale_id = sales.sale_id") + .joins("LEFT JOIN dining_facilities ON dining_facilities.id = bookings.dining_facility_id") + .completed.where.not(total_amount: 0) + .group("sales.sale_id") + + if customer_filter.present? + query = query.joins(sanitize_sql_array(["INNER JOIN customers ON customers.customer_id = sales.customer_id AND " + + "customers.name LIKE :filter", filter: "%#{customer_filter}%"])) + else + query = query.joins(:customer) + end + if !membership_type.blank? + query = query.where("customers.membership_type = (?)", membership_type) + end + + if shift.present? + query = query.where("sales.shift_sale_id in (?)", shift.to_a) + elsif shift_sale_range.present? + query = query.where("sales.shift_sale_id in (?)", shift_sale_range.to_a) + else + query = query.where("sales.receipt_date between ? and ?", from, to) + end + return query.group_by(&:membership_type) +end + def self.get_shift_sales_by_receipt_no_detail(shift_sale_range, shift, from, to, payment_type, customer_filter) ## => left join -> show all sales although no orders puts customer_filter diff --git a/app/views/layouts/_left_sidebar.html.erb b/app/views/layouts/_left_sidebar.html.erb index 4ca2f1ad..78e4c06a 100644 --- a/app/views/layouts/_left_sidebar.html.erb +++ b/app/views/layouts/_left_sidebar.html.erb @@ -324,6 +324,9 @@
  • Void Sales +
  • +
  • + Customer Sales
  • Wastes & Spoilages diff --git a/app/views/reports/customer/_shift_sale_report_filter.html.erb b/app/views/reports/customer/_shift_sale_report_filter.html.erb new file mode 100755 index 00000000..35819152 --- /dev/null +++ b/app/views/reports/customer/_shift_sale_report_filter.html.erb @@ -0,0 +1,144 @@ +
    + <%= form_tag report_path, :method => :get, :id=>"frm_report", :class => "form" do %> + <% if period_type != false %> +
    +
    + + +
    + +
    + + +
    + + <% if defined? @membership_type %> +
    + + + +
    + <% end %> + +
    + + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + <% end %> + + <% end %> +
    + + diff --git a/app/views/reports/customer/index.html.erb b/app/views/reports/customer/index.html.erb new file mode 100644 index 00000000..328de17f --- /dev/null +++ b/app/views/reports/customer/index.html.erb @@ -0,0 +1,286 @@ + + +
    +
    + + + <%= render :partial=>'shift_sale_report_filter', + :locals=>{ :period_type => true, :shift_name => true,:payments => true, :report_path =>reports_customer_index_path} %> +
    + + + + + + + + +
    +
    + + + + + + <% if @shift_from %> + + <% if @shift_data.employee %> + <% cashier_name = !@shift_data.nil? ? @shift_data.employee.name : '-' %> + <% end %> + + + <% end %> + + + + + + + + + <% @tax_profiles.each do |tax| %> + + <% end %> + + + + + + + <% t_grand_total = 0 %> + <% t_old_grand_total = 0 %> + <% t_total_sum = 0 %> + <% t_discount_amt = 0 %> + <% t_rounding_adj = 0%> + + <% if !@sale_data.nil? %> + + <% @sale_data.each do |member_group| %> + <% grand_total = 0 %> + <% old_grand_total = 0 %> + <% total_tax = [] %> + <% total_sum = 0 %> + <% discount_amt = 0 %> + <% rounding_adj = 0%> + + + <%if member_group[0].nil?%> + + <%else%> + + <%end%> + + + <% member_group[1].each do |result|%> + <% grand_total += result.grand_total.to_f %> + <% t_grand_total += result.grand_total.to_f %> + <% old_grand_total += result.grand_total.to_f - result.rounding_adjustment.to_f %> + <% t_old_grand_total += result.grand_total.to_f - result.rounding_adjustment.to_f%> + <% total_sum += result.total_amount.to_f %> + <% t_total_sum += result.total_amount.to_f %> + <% discount_amt += result.total_discount.to_f %> + <% t_discount_amt += result.total_discount.to_f %> + <% rounding_adj += result.rounding_adjustment.to_f %> + <% t_rounding_adj += result.rounding_adjustment.to_f %> + + + + + + + + + <% @tax_profiles.each do |tax| %> + <%tax_value=0%> + <% if sale_tax = result.sale_taxes.find { |sale_tax| sale_tax.tax_name == tax.name } %> + <%tax_value=sale_tax.tax_payable_amount%> + + <% else %> + + <% end %> + <%total_tax << { + tax.name => tax_value + }%> + <% end %> + + + + + <% end %> + + <% total_tax = total_tax.reduce {|acc, h| acc.merge(h) {|_,v1,v2| v1 + v2 }}%> + + + + <% @tax_profiles.each do |tax| %> + <%if total_tax.has_key?(tax.name)%> + + <%end%> + <% end %> + + + + + + + + <%end%> + + + + + + <% @tax_profiles.each do |tax| %> + + <% end %> + + + + + <%end%> + + + + + <% @tax_profiles.each do |tax| %> + <% if sale_tax = @sale_taxes.find { |sale_tax| sale_tax.tax_name == tax.name } %> + + <% else %> + + <% end %> + <% end %> + + + + + +
    <%= t("views.right_panel.detail.from_date") %> : <%= @from.utc.getlocal.strftime("%Y-%b-%d") rescue '-' %> - <%= t("views.right_panel.detail.to_date") %> : <%= @to.utc.getlocal.strftime("%Y-%b-%d") rescue '-'%>
    <%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> )
    <%= t("views.right_panel.detail.dining") %><%= t("views.right_panel.detail.receipt_no") %><%= t :customer %><%= t :cashier %><%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %><%= t("views.right_panel.detail.discount") %> <%= t("views.right_panel.detail.amount") %> <%= tax.name %><%= t("views.right_panel.detail.grand_total") %><%= t("views.right_panel.detail.rnd_adj_sh") %><%= t("views.right_panel.detail.grand_total") %> +
    + <%= t("views.right_panel.detail.rnd_adj_sh") %> +
    Group Type : Normal Group Type : <%= Lookup.where(:lookup_type=>'membership_type', :value=>member_group[0]).last.name %>
    + <%if result.type %> + <%= result.type %> - <%= result.name %> + <% else %> + - + <% end %> + <%= result.receipt_no rescue '-' %> <%= result.customer_name rescue '-' %><%= result.cashier_name rescue '-' %><%= number_format(result.total_amount, precision: precision.to_i, delimiter: delimiter) %><%= number_format(result.total_discount, precision: precision.to_i, delimiter: delimiter) rescue '0' %><%= number_format(sale_tax.tax_payable_amount, precision: precision.to_i, delimiter: delimiter) rescue '-' %> <%= number_format(0, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(result.grand_total - result.rounding_adjustment, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(result.rounding_adjustment.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(result.grand_total, precision: precision.to_i, delimiter: delimiter) rescue '-' %>
     <%= number_format(total_sum, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(discount_amt, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(total_tax[tax.name], precision: precision.to_i, delimiter: delimiter) rescue '-' %> <%= number_format(old_grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '0' %><%= number_format(rounding_adj.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %>
     
     <%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %><%= t("views.right_panel.detail.discount") %> <%= t("views.right_panel.detail.amount") %><%= tax.name %><%= t("views.right_panel.detail.grand_total") %><%= t("views.right_panel.detail.rnd_adj_sh") %><%= t("views.right_panel.detail.grand_total") %> +
    + <%= t("views.right_panel.detail.rnd_adj_sh") %> +
     <%= number_format(t_total_sum, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(t_discount_amt, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(sale_tax.st_amount, precision: precision.to_i, delimiter: delimiter) rescue '-' %> <%= number_format(0, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(t_old_grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '0' %><%= number_format(t_rounding_adj.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(t_grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %>
    +
    +
    +
    +
    + + diff --git a/app/views/reports/customer/index.xls.erb b/app/views/reports/customer/index.xls.erb new file mode 100644 index 00000000..9ebfe63a --- /dev/null +++ b/app/views/reports/customer/index.xls.erb @@ -0,0 +1,165 @@ + + + + + + + +
    +
    +
    +
    + + + + + + <% if @shift_from %> + + <% if @shift_data.employee %> + <% cashier_name = !@shift_data.nil? ? @shift_data.employee.name : '-' %> + <% end %> + + + <% end %> + + + + + + + + <% @tax_profiles.each do |tax| %> + + <% end %> + + + + + + + + + <% t_grand_total = 0 %> + <% t_old_grand_total = 0 %> + <% t_total_sum = 0 %> + <% t_discount_amt = 0 %> + <% t_rounding_adj = 0%> + + <% if @sale_data %> + <% @sale_data.each do |member_group| %> + <% grand_total = 0 %> + <% old_grand_total = 0 %> + <% total_tax = [] %> + <% total_sum = 0 %> + <% discount_amt = 0 %> + <% rounding_adj = 0%> + + + <%if member_group[0].nil?%> + + <%else%> + + <%end%> + + + <% member_group[1].each do |result|%> + <% grand_total += result.grand_total.to_f %> + <% t_grand_total += result.grand_total.to_f %> + <% old_grand_total += result.grand_total.to_f - result.rounding_adjustment.to_f %> + <% t_old_grand_total += result.grand_total.to_f - result.rounding_adjustment.to_f%> + <% total_sum += result.total_amount.to_f %> + <% t_total_sum += result.total_amount.to_f %> + <% discount_amt += result.total_discount.to_f %> + <% t_discount_amt += result.total_discount.to_f %> + <% rounding_adj += result.rounding_adjustment.to_f %> + <% t_rounding_adj += result.rounding_adjustment.to_f %> + + + + + + + + + <% @tax_profiles.each do |tax| %> + <%tax_value=0%> + <% if sale_tax = result.sale_taxes.find { |sale_tax| sale_tax.tax_name == tax.name } %> + <%tax_value=sale_tax.tax_payable_amount%> + + <% else %> + + <% end %> + <%total_tax << { + tax.name => tax_value + }%> + <% end %> + + + + + <% end %> + + <% total_tax = total_tax.reduce {|acc, h| acc.merge(h) {|_,v1,v2| v1 + v2 }}%> + + + + <% @tax_profiles.each do |tax| %> + <%if total_tax.has_key?(tax.name)%> + + <%end%> + <% end %> + + + + + + + + <%end%> + + + + + + <% @tax_profiles.each do |tax| %> + + <% end %> + + + + + <%end%> + + + + + <% @tax_profiles.each do |tax| %> + <% if sale_tax = @sale_taxes.find { |sale_tax| sale_tax.tax_name == tax.name } %> + + <% else %> + + <% end %> + <% end %> + + + + + +
    <%= t("views.right_panel.detail.from_date") %> : <%= @from.utc.getlocal.strftime("%Y-%b-%d") rescue '-' %> - <%= t("views.right_panel.detail.to_date") %> : <%= @to.utc.getlocal.strftime("%Y-%b-%d") rescue '-'%>
    <%= t("views.right_panel.detail.shift_name") %> = <%= @shift_from %> - <%= @shift_to %> ( <%= cashier_name %> )
    <%= t("views.right_panel.detail.dining") %><%= t("views.right_panel.detail.receipt_no") %><%= t :customer %><%= t :cashier %><%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %><%= t("views.right_panel.detail.discount") %> <%= t("views.right_panel.detail.amount") %> <%= tax.name %><%= t("views.right_panel.detail.grand_total") %><%= t("views.right_panel.detail.rnd_adj_sh") %><%= t("views.right_panel.detail.grand_total") %> +
    + <%= t("views.right_panel.detail.rnd_adj_sh") %> +
    Group Type : Normal Group Type : <%= Lookup.where(:lookup_type=>'membership_type', :value=>member_group[0]).last.name %>
    + <%if result.type %> + <%= result.type %> - <%= result.name %> + <% else %> + - + <% end %> + <%= result.receipt_no rescue '-' %> <%= result.customer_name rescue '-' %><%= result.cashier_name rescue '-' %><%= number_format(result.total_amount, precision: precision.to_i, delimiter: delimiter) %><%= number_format(result.total_discount, precision: precision.to_i, delimiter: delimiter) rescue '0' %><%= number_format(sale_tax.tax_payable_amount, precision: precision.to_i, delimiter: delimiter) rescue '-' %> <%= number_format(0, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(result.grand_total - result.rounding_adjustment, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(result.rounding_adjustment.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(result.grand_total, precision: precision.to_i, delimiter: delimiter) rescue '-' %>
     <%= number_format(total_sum, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(discount_amt, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(total_tax[tax.name], precision: precision.to_i, delimiter: delimiter) rescue '-' %> <%= number_format(old_grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '0' %><%= number_format(rounding_adj.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %>
     
     <%= t("views.right_panel.detail.total") %> <%= t("views.right_panel.detail.amount") %><%= t("views.right_panel.detail.discount") %> <%= t("views.right_panel.detail.amount") %><%= tax.name %><%= t("views.right_panel.detail.grand_total") %><%= t("views.right_panel.detail.rnd_adj_sh") %><%= t("views.right_panel.detail.grand_total") %> +
    + <%= t("views.right_panel.detail.rnd_adj_sh") %> +
     <%= number_format(t_total_sum, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(t_discount_amt, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(sale_tax.st_amount, precision: precision.to_i, delimiter: delimiter) rescue '-' %> <%= number_format(0, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(t_old_grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '0' %><%= number_format(t_rounding_adj.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %><%= number_format(t_grand_total.to_f, precision: precision.to_i, delimiter: delimiter) rescue '-' %>
    +
    +
    +
    +
    + + diff --git a/config/routes.rb b/config/routes.rb index 5fb08e4c..11b3fe90 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -546,6 +546,7 @@ scope "(:locale)", locale: /en|mm/ do namespace :reports do resources :receipt_no resources :receipt_no_detail + resources :customer, :only => [:index, :show] resources :dailysale, :only => [:index, :show] resources :saleitem, :only => [:index, :show] resources :hourly_saleitem, :only => [:index, :show]