Business-OCV

 view release on metacpan or  search on metacpan

utilities/totals  view on Meta::CPAN


	# extract prefix and Message from log entry
	my ($p, $m) = OCV::parsetxnlog($_);
	$@ = "error: OCV::parsetxnlog: $@", next unless ($p and $m);

	# all transaction message types have a type and reference id
	my $type = $m->Type;
	$@ = "error: no message type found", next unless $type;

	my $txnref = $m->TxnRef;
	$@ = "error: no TxnRef found", next unless $txnref;

	# 1) add purchase & refunds to scratch summary
	#    - will be completed when response entry is found containing the
	#     settlement date
	#    - hang on to the account number too, as not all responses have it
	# 2) add 'completed' entries to totals summary
	if ($type == OCV::TT_TRANS_PURCHASE or $type == OCV::TT_TRANS_COMPLETION)
	{
		warn "$txnref PURCHASE\n" if $DEBUG > 1;
		
		$@ = "error: duplicate txn reference (PURCHASE): [$txnref]", next 
			if (exists $txn{$txnref});

		$txn{$txnref} = [$m->Amount, $m->AccountNum];
	}
	elsif ($type == OCV::TT_TRANS_REFUND)
	{
		warn "$txnref REFUND\n" if $DEBUG > 1;
		$@ = "error: duplicate txn reference (REFUND): [$txnref]", next
			if (exists $txn{$txnref});

		$txn{$txnref} = [-$m->Amount, $m->AccountNum];
	}
	elsif ($type == OCV::TT_TRANS_RESPONSE)
	{
		warn "$txnref RESPONSE\n" if $DEBUG > 1;
		# a RESPONSE can be received in response to a PURCHASE/REFUND
		# or a STATUS
		# - STATUS transactions are 'duplicates', and are ignored
		# - completed transactions are marked by $txn{$txnref} == undef
		#   - i.e. an totally unknown txn will not have a key in %txn, an
		#     already processed txn will have $txn{$txnref} == undef, and
		#     a transaction that is half-complete will have the amount + 
		#     account number

		# confirm purchase/refund request has been encountered
		$@ = "error: RESPONSE for unknown transaction: [$txnref]", next
			unless (exists $txn{$txnref});

		warn "REQUEST found: " . (defined $txn{$txnref} ? 'yes' : 'no') . "\n"
			if $DEBUG > 2;

		# RESPONSE for completed transaction (e.g. from superfluous STATUS)
		next unless defined $txn{$txnref};

		# ok, extract the PURCHASE data (the amount) 
		my ($amt, $a) = @{$txn{$txnref}};

		# if the response is 'final', cross it off
		# - server may have been busy, one or more RESPONSEs should be
		#   forthcoming containing the final txn status
		$txn{$txnref} = undef unless $m->Retry;

		# extract the most-used fields once
		# - excuse the abbreviated variable names, I'm a lazy typist :-)
		my ($r, $d, $c) = ($m->Result, $m->SettleDate, $m->CardBin);

		warn "SettleDate = $d\n" if $DEBUG == 2;
		warn "SettleDate = $d, Result = $r, AccountNum = $a\n" if $DEBUG > 2;

		# skip if we're after a specific account/date, and this isn't it
		next if (defined $account and $a != $account);
		next if (defined $date and $d !~ /$date/);

		# what type of RESPONSE have I?
		# - keep track of non approved transactions in 'metadata' keys
		$summary{$a}{'results'} = {} unless ($summary{$a}{'results'});
		if ($r == OCV::TRANS_DECLINED)
		{
			$summary{$a}{'results'}{'declined'}++;
			next;
		}
		elsif ($r == OCV::TRANS_INPROGRESS)
		{
			$summary{$a}{'results'}{'inprogress'}++;
			# warn, as this may indicate a problem (or may not :-)
			$@ = "Txn [$txnref] InProgress";
			next;
		}
		elsif ($r != OCV::TRANS_APPROVED)	# what else?
		{
			$summary{$a}{'results'}{'unknown'}++;
			$@ = "unknown Result type: [$r]";
			next;
		}

		# just for the heck of it, confirm the account numbers match
		# - only 'approved' txns seem to have account numbers in the response
		# - an account 'number' could conceivably be a string...
		# - a further warning, if any, will override this one
		$@ = "Account numbers mismatch! [$txnref]: [$a] vs. [" . 
			$m->AccountNum . "]" unless $a eq $m->AccountNum;

		warn "adding $txnref (STAN = " . $m->STAN . ") to summary\n" if $DEBUG;

		# new account number?
		$summary{$a}     = {} unless ($summary{$a});

		# a given account will use one or more (merchant ID, terminal ID) pairs
		# - save this 'meta-data' in a special key, to be presented with the
		#   totals summary
		$summary{$a}{'midtid'} = {} unless ($summary{$a}{'midtid'});
		$_ = $m->MerchantID . ':' . $m->TerminalID;
		$summary{$a}{'midtid'}{$_}++;

		# new settlement date?
		$summary{$a}{$d} = {} unless ($summary{$a}{$d});

		# initialise new card structure?
		unless ($summary{$a}{$d}{$c})



( run in 0.599 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )