public function autoBillInvoice(Invoice $invoice)
{
/** @var \App\Models\Client $client */
$client = $invoice->client;
/** @var \App\Models\Account $account */
$account = $client->account;
/** @var \App\Models\Invitation $invitation */
$invitation = $invoice->invitations->first();
if (!$invitation) {
return false;
}
if ($credits = $client->credits->sum('balance')) {
$balance = $invoice->balance;
$amount = min($credits, $balance);
$data = ['payment_type_id' => PAYMENT_TYPE_CREDIT, 'invoice_id' => $invoice->id, 'client_id' => $client->id, 'amount' => $amount];
$payment = $this->paymentRepo->save($data);
if ($amount == $balance) {
return $payment;
}
}
$paymentDriver = $account->paymentDriver($invitation, GATEWAY_TYPE_TOKEN);
if (!$paymentDriver) {
return false;
}
$customer = $paymentDriver->customer();
if (!$customer) {
return false;
}
$paymentMethod = $customer->default_payment_method;
if ($paymentMethod->requiresDelayedAutoBill()) {
$invoiceDate = \DateTime::createFromFormat('Y-m-d', $invoice->invoice_date);
$minDueDate = clone $invoiceDate;
$minDueDate->modify('+10 days');
if (date_create() < $minDueDate) {
// Can't auto bill now
return false;
}
if ($invoice->partial > 0) {
// The amount would be different than the amount in the email
return false;
}
$firstUpdate = Activity::where('invoice_id', '=', $invoice->id)->where('activity_type_id', '=', ACTIVITY_TYPE_UPDATE_INVOICE)->first();
if ($firstUpdate) {
$backup = json_decode($firstUpdate->json_backup);
if ($backup->balance != $invoice->balance || $backup->due_date != $invoice->due_date) {
// It's changed since we sent the email can't bill now
return false;
}
}
if ($invoice->payments->count()) {
// ACH requirements are strict; don't auto bill this
return false;
}
}
return $paymentDriver->completeOnsitePurchase(false, $paymentMethod);
}