#!/usr/bin/perl

use strict;
use warnings;
use File::Find qw( find );
use FindBin qw( $Bin );
use lib "/opt/pos/lib";
use lib "$Bin/../../lib";
use POSIX qw( strftime );
use Data::Dumper;
use Date::Calc qw( Days_in_Month );
use DBI;
use Storable;
use File::Find qw( find );

use App::POS::Config;
use App::POS::Utils qw( send_mail );
use App::POS::DB::Postgres;

#
# Crontab entry:
#
# */5 * * * * /root/voids_send mmanso@gmail.com 5
#

my $cfg = App::POS::Config->new( file => "/opt/pos/etc/config.ini" );
my $info = $cfg->load();
my $dsn = 'DBI:Pg:dbname=pos;host=127.0.0.1';
my $user = 'root';
my $passwd = '';

my $db = App::POS::DB::Postgres->new(dbh => DBI->connect($dsn,$user,$passwd,{}));

my @voids = ();

# fetch product's names
my %pnames = ();

my $recs = $db->select("SELECT id, name FROM products");

for (@$recs) {
  $pnames{ $_->{id} } = $_->{name};
}

# fetch clerk's names
my %cnames = ();

$recs = $db->select("SELECT id, login FROM clerks");

for (@$recs) {
  $cnames{ $_->{id} } = $_->{login};
}

my %voids_on_tables = ();

# find voids in open tables
find( sub {
  return unless /\.deleted$/;

  my $fname = $_;
  $fname =~ s/\.deleted$//;

  open(F, "< $File::Find::name");
  while (<F>) {
    my $l = $_;
    chop($l);

    my @t = split /#/, $l;

    my $gbi = $t[-1];

    my $pname = $pnames{$t[1]};
    my $hour_tmp = $t[2];
    my @void_info = split /@/, $hour_tmp;
    my $hour_void = $void_info[1];
    my $clerk_id = $t[7];
    my $clerk_name = $cnames{ $clerk_id };
    my $total = $t[3] * $t[4];

    # hour void + product
    my $key = $hour_void . "#" . $t[1];

    $voids_on_tables{$key} = {
      product_name => $pname,
      hour => $hour_void,
      total => sprintf("%.2f", $total),
      table_num => $fname,
      clerk_name => $clerk_name,
    };
  }
  close(F);
}, ( "/opt/pos/server/data/areas" ) );

my $to = shift;
my $void_limit = shift;

die "Usage: $0 <to_email> <void_limit>\n" unless defined $to && defined $void_limit;

my $sent = {};

if (-e "/tmp/voids_sent.db") {
  $sent = retrieve("/tmp/voids_sent.db");
}

die "Missing /opt/pos/.business_date" unless -e "/opt/pos/.business_date";

my $date = "";

{
  local $/ = undef;
  open(F, "< /opt/pos/.business_date");
  $date = <F>;
  chop($date);
  close(F);
}

die "Can't find business_date..." unless $date;

my $cnt = "";
my @did_ids = ();
my $html = "";

foreach my $k (keys %voids_on_tables) {
  my $r = $voids_on_tables{$k};

  next if exists $sent->{$k};
  next if $r->{total} < $void_limit;

  if (! $html) {
    $html = "<html><body><h1>Anulacao POS</h1><table border=1>".
      "<tr><td><b>Hora</td><td><b>Mesa</td><td><b>Func</td><td><b>Produto</td><td><b>Valor</td></tr>";
  }

  $html .= "<tr><td>".$r->{hour}."</td><td>".$r->{table_num}."</td><td>".$r->{clerk_name}.
    "</td><td>".$r->{product_name}."</td><td align=right>".sprintf("%.2f", $r->{total})."</td></tr>";

  push @did_ids, $k;
}

$recs = $db->select(qq{
  SELECT sd.hour, sd.gb_identifier AS id, sh.table_num, sh.business_date, sh.fo_doc_number,
    sd.product_name, sd.clerk_name, sd.product, SUM(sd.quantity*sd.price) AS total
  FROM sales_details sd
  LEFT JOIN sales_headers sh ON (sd.header = sh.id)
  WHERE sh.business_date = ? AND sd.operation_type = 2
  GROUP BY sd.hour, sh.table_num, sd.gb_identifier, sh.business_date, sh.fo_doc_number, sd.product_name, sd.clerk_name, sd.product
  ORDER BY sh.fo_doc_number
}, $date);

foreach my $r (@$recs) {
  # hour void + product
  my $key = $r->{hour} . "#" . $r->{product};

  next if exists $sent->{$key};
  next if $r->{total} < $void_limit;

  if (! $html) {
    $html = "<html><body><h1>Anulacao POS</h1><table border=1>".
      "<tr><td><b>Hora</td><td><b>Mesa</td><td><b>Func</td><td><b>Produto</td><td><b>Valor</td></tr>";
  }

  $html .= "<tr><td>".$r->{hour}."</td><td>".$r->{table_num}."</td><td>".$r->{clerk_name}.
    "</td><td>".$r->{product_name}."</td><td align=right>".sprintf("%.2f", $r->{total})."</td></tr>";

  push @did_ids, $key;
}


if ($html) {
  $html .= "</table></body></html>";

  print STDERR "Will send email...\n";

  my $stat = send_mail(
    to         => $to,
    subject    => "* ANULACAO POS (".&strftime("%Y-%m-%d %H:%M:%S", localtime).") *",
    content    => $html,
    attachment => [],
  );

  if ($stat) {
    for (@did_ids) {
      $sent->{$_} = 1;
    }
  }
}

store $sent, '/tmp/voids_sent.db';

