mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #10052 from turbo124/v5-develop
Fixes for product sales export
This commit is contained in:
commit
9e78ead76c
@ -23,7 +23,7 @@ use League\Csv\Writer;
|
|||||||
|
|
||||||
class ProductSalesExport extends BaseExport
|
class ProductSalesExport extends BaseExport
|
||||||
{
|
{
|
||||||
public string $date_key = 'created_at';
|
public string $date_key = 'date';
|
||||||
|
|
||||||
/** @var Collection<\App\Models\Product> $products*/
|
/** @var Collection<\App\Models\Product> $products*/
|
||||||
protected Collection $products;
|
protected Collection $products;
|
||||||
|
@ -255,7 +255,7 @@ abstract class QueryFilters
|
|||||||
|
|
||||||
public function client_id(string $client_id = ''): Builder
|
public function client_id(string $client_id = ''): Builder
|
||||||
{
|
{
|
||||||
if (strlen($client_id) == 0) {
|
if (strlen($client_id) == 0 || !in_array('vendor_id', \Illuminate\Support\Facades\Schema::getColumnListing($this->builder->getModel()->getTable()))) {
|
||||||
return $this->builder;
|
return $this->builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ abstract class QueryFilters
|
|||||||
|
|
||||||
public function vendor_id(string $vendor_id = ''): Builder
|
public function vendor_id(string $vendor_id = ''): Builder
|
||||||
{
|
{
|
||||||
if (strlen($vendor_id) == 0) {
|
if (strlen($vendor_id) == 0 || !in_array('vendor_id', \Illuminate\Support\Facades\Schema::getColumnListing($this->builder->getModel()->getTable()))) {
|
||||||
return $this->builder;
|
return $this->builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,6 +251,12 @@ class CompanyGatewayController extends BaseController
|
|||||||
$company_gateway->driver()->init()->settings()->updateSettings();
|
$company_gateway->driver()->init()->settings()->updateSettings();
|
||||||
})->afterResponse();
|
})->afterResponse();
|
||||||
|
|
||||||
|
$config = $company_gateway->getConfig();
|
||||||
|
$config->visa = true;
|
||||||
|
$config->mastercard = true;
|
||||||
|
$company_gateway->setConfig($config);
|
||||||
|
$company_gateway->save();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -93,11 +93,13 @@ class StoreInvoiceRequest extends Request
|
|||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
if(\Illuminate\Support\Facades\Cache::has($this->ip()."|INVOICE|".$this->input('client_id', '')."|".$user->company()->company_key)) {
|
$client_id = is_string($this->input('client_id', '')) ? $this->input('client_id') : '';
|
||||||
|
|
||||||
|
if(\Illuminate\Support\Facades\Cache::has($this->ip()."|INVOICE|".$client_id."|".$user->company()->company_key)) {
|
||||||
usleep(200000);
|
usleep(200000);
|
||||||
}
|
}
|
||||||
|
|
||||||
\Illuminate\Support\Facades\Cache::put($this->ip()."|INVOICE|".$this->input('client_id', '')."|".$user->company()->company_key,1);
|
\Illuminate\Support\Facades\Cache::put($this->ip()."|INVOICE|".$client_id."|".$user->company()->company_key,1);
|
||||||
|
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
|
@ -80,11 +80,13 @@ class StorePaymentRequest extends Request
|
|||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
if(\Illuminate\Support\Facades\Cache::has($this->ip()."|".$this->input('amount', 0)."|".$this->input('client_id', '')."|".$user->company()->company_key)) {
|
$client_id = is_string($this->input('client_id', '')) ? $this->input('client_id') : '';
|
||||||
|
|
||||||
|
if(\Illuminate\Support\Facades\Cache::has($this->ip()."|".$this->input('amount', 0)."|".$client_id."|".$user->company()->company_key)) {
|
||||||
throw new DuplicatePaymentException('Duplicate request.', 429);
|
throw new DuplicatePaymentException('Duplicate request.', 429);
|
||||||
}
|
}
|
||||||
|
|
||||||
\Illuminate\Support\Facades\Cache::put(($this->ip()."|".$this->input('amount', 0)."|".$this->input('client_id', '')."|".$user->company()->company_key), true, 1);
|
\Illuminate\Support\Facades\Cache::put(($this->ip()."|".$this->input('amount', 0)."|".$client_id."|".$user->company()->company_key), true, 1);
|
||||||
|
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
@ -105,7 +107,7 @@ class StorePaymentRequest extends Request
|
|||||||
$input['invoices'][$key]['invoice_id'] = $this->decodePrimaryKey($value['invoice_id']);
|
$input['invoices'][$key]['invoice_id'] = $this->decodePrimaryKey($value['invoice_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('amount', $value)) {
|
if (array_key_exists('amount', $value) && is_numeric($value['amount'])) {
|
||||||
$invoices_total += $value['amount'];
|
$invoices_total += $value['amount'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,10 +121,13 @@ class StorePaymentRequest extends Request
|
|||||||
foreach ($input['credits'] as $key => $value) {
|
foreach ($input['credits'] as $key => $value) {
|
||||||
if (isset($value['credit_id']) && is_string($value['credit_id'])) {
|
if (isset($value['credit_id']) && is_string($value['credit_id'])) {
|
||||||
$input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($value['credit_id']);
|
$input['credits'][$key]['credit_id'] = $this->decodePrimaryKey($value['credit_id']);
|
||||||
|
|
||||||
|
if (array_key_exists('amount', $value) && is_numeric($value['amount'])) {
|
||||||
$credits_total += $value['amount'];
|
$credits_total += $value['amount'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($input['credits']) && is_array($input['credits']) === false) {
|
if (isset($input['credits']) && is_array($input['credits']) === false) {
|
||||||
$input['credits'] = null;
|
$input['credits'] = null;
|
||||||
|
@ -100,7 +100,7 @@ class UpdatePaymentRequest extends Request
|
|||||||
public function messages()
|
public function messages()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'distinct' => 'Attemping duplicate payment on the same invoice Invoice',
|
'distinct' => 'Attemping duplicate payment on the same Invoice',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,8 @@ class StoreSchedulerRequest extends Request
|
|||||||
'parameters' => 'bail|array',
|
'parameters' => 'bail|array',
|
||||||
'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()],
|
'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()],
|
||||||
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all',
|
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all',
|
||||||
'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'],
|
'parameters.start_date' => ['bail', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'],
|
||||||
'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
|
'parameters.end_date' => ['bail', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
|
||||||
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
|
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
|
||||||
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
|
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
|
||||||
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:vendor,purchase_order_item,purchase_order,ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,activity,activities,client,clients,client_contact,client_contacts,credit,credits,document,documents,expense,expenses,invoice,invoices,invoice_item,invoice_items,quote,quotes,quote_item,quote_items,recurring_invoice,recurring_invoices,payment,payments,product,products,task,tasks'],
|
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:vendor,purchase_order_item,purchase_order,ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,activity,activities,client,clients,client_contact,client_contacts,credit,credits,document,documents,expense,expenses,invoice,invoices,invoice_item,invoice_items,quote,quotes,quote_item,quote_items,recurring_invoice,recurring_invoices,payment,payments,product,products,task,tasks'],
|
||||||
|
@ -36,6 +36,7 @@ class InvoiceTransformer extends BaseTransformer
|
|||||||
$invoiceStatusMap = [
|
$invoiceStatusMap = [
|
||||||
'sent' => Invoice::STATUS_SENT,
|
'sent' => Invoice::STATUS_SENT,
|
||||||
'draft' => Invoice::STATUS_DRAFT,
|
'draft' => Invoice::STATUS_DRAFT,
|
||||||
|
'paid' => Invoice::STATUS_PAID,
|
||||||
];
|
];
|
||||||
|
|
||||||
$transformed = [
|
$transformed = [
|
||||||
|
@ -11,31 +11,32 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Mail;
|
namespace App\Jobs\Mail;
|
||||||
|
|
||||||
use App\DataMapper\Analytics\EmailFailure;
|
use App\Models\User;
|
||||||
use App\DataMapper\Analytics\EmailSuccess;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
|
|
||||||
use App\Events\Payment\PaymentWasEmailedAndFailed;
|
|
||||||
use App\Jobs\Util\SystemLogger;
|
|
||||||
use App\Libraries\Google\Google;
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\ClientContact;
|
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use App\Models\User;
|
use App\Libraries\MultiDB;
|
||||||
use App\Utils\Ninja;
|
use App\Models\ClientContact;
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use GuzzleHttp\Exception\ClientException;
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Libraries\Google\Google;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Postmark\Models\PostmarkException;
|
||||||
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use GuzzleHttp\Exception\ClientException;
|
||||||
|
use App\DataMapper\Analytics\EmailFailure;
|
||||||
|
use App\DataMapper\Analytics\EmailSuccess;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use App\Events\Payment\PaymentWasEmailedAndFailed;
|
||||||
use Illuminate\Support\Facades\App;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
|
||||||
|
|
||||||
/*Multi Mailer implemented*/
|
/*Multi Mailer implemented*/
|
||||||
|
|
||||||
@ -242,6 +243,21 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post mark buries the proper message in a guzzle response
|
||||||
|
* this merges a text string with a json object
|
||||||
|
* need to harvest the ->Message property using the following
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($e instanceof PostmarkException) { //postmark specific failure
|
||||||
|
|
||||||
|
$this->fail();
|
||||||
|
$this->entityEmailFailed($e->getMessage());
|
||||||
|
$this->cleanUpMailers();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//only report once, not on all tries
|
//only report once, not on all tries
|
||||||
if ($this->attempts() == $this->tries) {
|
if ($this->attempts() == $this->tries) {
|
||||||
/* If there is an entity attached to the message send a failure mailer */
|
/* If there is an entity attached to the message send a failure mailer */
|
||||||
@ -249,10 +265,8 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
$this->entityEmailFailed($message);
|
$this->entityEmailFailed($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't send postmark failures to Sentry */
|
|
||||||
if (Ninja::isHosted() && (!$e instanceof ClientException)) {
|
|
||||||
app('sentry')->captureException($e);
|
app('sentry')->captureException($e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Releasing immediately does not add in the backoff */
|
/* Releasing immediately does not add in the backoff */
|
||||||
|
@ -57,13 +57,13 @@ class TaskScheduler implements ShouldQueue
|
|||||||
->cursor()
|
->cursor()
|
||||||
->each(function ($scheduler) {
|
->each(function ($scheduler) {
|
||||||
|
|
||||||
nlog("Doing job {$scheduler->name}");
|
nlog("Doing job ::{$scheduler->id}:: {$scheduler->name}");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//@var \App\Models\Schedule $scheduler
|
//@var \App\Models\Schedule $scheduler
|
||||||
$scheduler->service()->runTask();
|
$scheduler->service()->runTask();
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
nlog("Exception:: TaskScheduler:: Doing job {$scheduler->name}" . $e->getMessage());
|
nlog("Exception:: TaskScheduler:: Doing job :: {$scheduler->id} :: {$scheduler->name}" . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -83,13 +83,13 @@ class TaskScheduler implements ShouldQueue
|
|||||||
->cursor()
|
->cursor()
|
||||||
->each(function ($scheduler) {
|
->each(function ($scheduler) {
|
||||||
|
|
||||||
nlog("Doing job {$scheduler->name}");
|
nlog("Doing job ::{$scheduler->id}:: {$scheduler->name}");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/** @var \App\Models\Scheduler $scheduler */
|
/** @var \App\Models\Scheduler $scheduler */
|
||||||
$scheduler->service()->runTask();
|
$scheduler->service()->runTask();
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
nlog("Exception:: TaskScheduler::" . $e->getMessage());
|
nlog("Exception:: TaskScheduler:: #{$scheduler->id}::" . $e->getMessage());
|
||||||
nlog($e->getMessage());
|
nlog($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
|||||||
return SystemLog::query()
|
return SystemLog::query()
|
||||||
->where('company_id', $this->invitation->company_id)
|
->where('company_id', $this->invitation->company_id)
|
||||||
->where('type_id', SystemLog::TYPE_WEBHOOK_RESPONSE)
|
->where('type_id', SystemLog::TYPE_WEBHOOK_RESPONSE)
|
||||||
|
->where('category_id', SystemLog::CATEGORY_MAIL)
|
||||||
|
// ->where('client_id', $this->invitation->contact->client_id)
|
||||||
->whereJsonContains('log', ['MessageID' => $message_id])
|
->whereJsonContains('log', ['MessageID' => $message_id])
|
||||||
->orderBy('id', 'desc')
|
->orderBy('id', 'desc')
|
||||||
->first();
|
->first();
|
||||||
|
@ -50,8 +50,6 @@ class SendRecurring implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function __construct(public RecurringInvoice $recurring_invoice, public string $db = 'db-ninja-01')
|
public function __construct(public RecurringInvoice $recurring_invoice, public string $db = 'db-ninja-01')
|
||||||
{
|
{
|
||||||
$this->recurring_invoice = $recurring_invoice;
|
|
||||||
$this->db = $db;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,7 +71,7 @@ class ReminderJob implements ShouldQueue
|
|||||||
->whereHas('company', function ($query) {
|
->whereHas('company', function ($query) {
|
||||||
$query->where('is_disabled', 0);
|
$query->where('is_disabled', 0);
|
||||||
})
|
})
|
||||||
->with('invitations')->chunk(200, function ($invoices) {
|
->with('invitations')->chunk(800, function ($invoices) {
|
||||||
foreach ($invoices as $invoice) {
|
foreach ($invoices as $invoice) {
|
||||||
$this->sendReminderForInvoice($invoice);
|
$this->sendReminderForInvoice($invoice);
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ class ReminderJob implements ShouldQueue
|
|||||||
->whereHas('company', function ($query) {
|
->whereHas('company', function ($query) {
|
||||||
$query->where('is_disabled', 0);
|
$query->where('is_disabled', 0);
|
||||||
})
|
})
|
||||||
->with('invitations')->chunk(200, function ($invoices) {
|
->with('invitations')->chunk(800, function ($invoices) {
|
||||||
|
|
||||||
foreach ($invoices as $invoice) {
|
foreach ($invoices as $invoice) {
|
||||||
$this->sendReminderForInvoice($invoice);
|
$this->sendReminderForInvoice($invoice);
|
||||||
|
@ -297,7 +297,7 @@ class ClientContact extends Authenticatable implements HasLocalePreference
|
|||||||
|
|
||||||
return $languages->first(function ($item) {
|
return $languages->first(function ($item) {
|
||||||
return $item->id == $this->client->getSetting('language_id');
|
return $item->id == $this->client->getSetting('language_id');
|
||||||
})->locale;
|
})->locale ?? 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function routeNotificationForMail($notification)
|
public function routeNotificationForMail($notification)
|
||||||
|
@ -368,7 +368,7 @@ class Invoice extends BaseModel
|
|||||||
|
|
||||||
public function activities()
|
public function activities()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(50);
|
return $this->hasMany(Activity::class)->where('company_id', $this->company_id)->where('client_id', $this->client_id)->orderBy('id', 'DESC')->take(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,7 +189,7 @@ class VendorContact extends Authenticatable implements HasLocalePreference
|
|||||||
|
|
||||||
return $languages->first(function ($item) {
|
return $languages->first(function ($item) {
|
||||||
return $item->id == $this->company->getSetting('language_id');
|
return $item->id == $this->company->getSetting('language_id');
|
||||||
})->locale;
|
})->locale ?? 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -218,8 +218,27 @@ class CreditCard implements LivewireMethodInterface
|
|||||||
{
|
{
|
||||||
$this->powerboard->init();
|
$this->powerboard->init();
|
||||||
|
|
||||||
// if(!isset($this->cba_gateway->verification_status) || $this->cba_gateway->verification_status != "completed")
|
$available_cards = [
|
||||||
// throw new PaymentFailed("This payment method is not configured as yet. Reference Powerboard portal for further information", 400);
|
"amex",
|
||||||
|
"ausbc",
|
||||||
|
"discover",
|
||||||
|
"japcb",
|
||||||
|
"laser",
|
||||||
|
"mastercard",
|
||||||
|
"solo",
|
||||||
|
"visa",
|
||||||
|
"visa_white",
|
||||||
|
];
|
||||||
|
|
||||||
|
$supported_cards = $this->powerboard->company_gateway->getConfig();
|
||||||
|
|
||||||
|
$supported_cards_array = [];
|
||||||
|
|
||||||
|
foreach($available_cards as $card){
|
||||||
|
if($supported_cards->{$card}){
|
||||||
|
$supported_cards_array[] = $card;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$merge = [
|
$merge = [
|
||||||
'public_key' => $this->powerboard->company_gateway->getConfigField('publicKey'),
|
'public_key' => $this->powerboard->company_gateway->getConfigField('publicKey'),
|
||||||
@ -227,6 +246,7 @@ class CreditCard implements LivewireMethodInterface
|
|||||||
'gateway' => $this->powerboard,
|
'gateway' => $this->powerboard,
|
||||||
'environment' => $this->powerboard->environment,
|
'environment' => $this->powerboard->environment,
|
||||||
'gateway_id' => $this->cba_gateway->_id ?? false,
|
'gateway_id' => $this->cba_gateway->_id ?? false,
|
||||||
|
'supported_cards' => $supported_cards_array,
|
||||||
];
|
];
|
||||||
|
|
||||||
return array_merge($data, $merge);
|
return array_merge($data, $merge);
|
||||||
|
@ -176,6 +176,19 @@ class IDEAL implements MethodInterface, LivewireMethodInterface
|
|||||||
*/
|
*/
|
||||||
public function processSuccessfulPayment(\Mollie\Api\Resources\Payment $payment, string $status = 'paid'): RedirectResponse
|
public function processSuccessfulPayment(\Mollie\Api\Resources\Payment $payment, string $status = 'paid'): RedirectResponse
|
||||||
{
|
{
|
||||||
|
$p = \App\Models\Payment::query()
|
||||||
|
->withTrashed()
|
||||||
|
->where('company_id', $this->mollie->client->company_id)
|
||||||
|
->where('transaction_reference', $payment->id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if($p) {
|
||||||
|
$p->status_id = Payment::STATUS_COMPLETED;
|
||||||
|
$p->save();
|
||||||
|
|
||||||
|
return redirect()->route('client.payments.show', ['payment' => $p->hashed_id]);
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'gateway_type_id' => GatewayType::IDEAL,
|
'gateway_type_id' => GatewayType::IDEAL,
|
||||||
'amount' => array_sum(array_column($this->mollie->payment_hash->invoices(), 'amount')) + $this->mollie->payment_hash->fee_total,
|
'amount' => array_sum(array_column($this->mollie->payment_hash->invoices(), 'amount')) + $this->mollie->payment_hash->fee_total,
|
||||||
|
@ -287,7 +287,7 @@ class MolliePaymentDriver extends BaseDriver
|
|||||||
{
|
{
|
||||||
// Allow app to catch up with webhook request.
|
// Allow app to catch up with webhook request.
|
||||||
// sleep(4);
|
// sleep(4);
|
||||||
usleep(rand(2800000, 4000000));
|
usleep(rand(1500000, 4000000));
|
||||||
|
|
||||||
$validator = Validator::make($request->all(), [
|
$validator = Validator::make($request->all(), [
|
||||||
'id' => ['required', 'starts_with:tr'],
|
'id' => ['required', 'starts_with:tr'],
|
||||||
|
@ -11,38 +11,39 @@
|
|||||||
|
|
||||||
namespace App\Services\Email;
|
namespace App\Services\Email;
|
||||||
|
|
||||||
use App\DataMapper\Analytics\EmailFailure;
|
use Log;
|
||||||
use App\DataMapper\Analytics\EmailSuccess;
|
use App\Models\User;
|
||||||
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Payment\PaymentWasEmailedAndFailed;
|
|
||||||
use App\Jobs\Util\SystemLogger;
|
|
||||||
use App\Libraries\Google\Google;
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Mail\Engine\PaymentEmailEngine;
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
use App\Models\Vendor;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Vendor;
|
|
||||||
use App\Models\VendorContact;
|
|
||||||
use App\Utils\HtmlEngine;
|
use App\Utils\HtmlEngine;
|
||||||
use App\Utils\Ninja;
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Utils\VendorHtmlEngine;
|
use App\Utils\VendorHtmlEngine;
|
||||||
|
use App\Libraries\Google\Google;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Postmark\Models\PostmarkException;
|
||||||
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
use App\Mail\Engine\PaymentEmailEngine;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use GuzzleHttp\Exception\ClientException;
|
use GuzzleHttp\Exception\ClientException;
|
||||||
use Illuminate\Bus\Queueable;
|
use App\DataMapper\Analytics\EmailFailure;
|
||||||
|
use App\DataMapper\Analytics\EmailSuccess;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Mail\Mailable;
|
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use App\Events\Payment\PaymentWasEmailedAndFailed;
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Log;
|
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
|
||||||
|
|
||||||
class Email implements ShouldQueue
|
class Email implements ShouldQueue
|
||||||
{
|
{
|
||||||
@ -375,16 +376,10 @@ class Email implements ShouldQueue
|
|||||||
* this merges a text string with a json object
|
* this merges a text string with a json object
|
||||||
* need to harvest the ->Message property using the following
|
* need to harvest the ->Message property using the following
|
||||||
*/
|
*/
|
||||||
if ($e instanceof ClientException) { //postmark specific failure
|
if ($e instanceof PostmarkException) { //postmark specific failure
|
||||||
$response = $e->getResponse();
|
|
||||||
$message_body = json_decode($response->getBody()->getContents());
|
|
||||||
|
|
||||||
if ($message_body && property_exists($message_body, 'Message')) {
|
|
||||||
$message = $message_body->Message;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->fail();
|
$this->fail();
|
||||||
$this->entityEmailFailed($message);
|
$this->entityEmailFailed($e->getMessage());
|
||||||
$this->cleanUpMailers();
|
$this->cleanUpMailers();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -395,10 +390,8 @@ class Email implements ShouldQueue
|
|||||||
/* If the is an entity attached to the message send a failure mailer */
|
/* If the is an entity attached to the message send a failure mailer */
|
||||||
$this->entityEmailFailed($message);
|
$this->entityEmailFailed($message);
|
||||||
|
|
||||||
/* Don't send postmark failures to Sentry */
|
|
||||||
if (Ninja::isHosted() && (!$e instanceof ClientException)) {
|
|
||||||
app('sentry')->captureException($e);
|
app('sentry')->captureException($e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->tearDown();
|
$this->tearDown();
|
||||||
@ -985,7 +978,7 @@ class Email implements ShouldQueue
|
|||||||
* @param string $message
|
* @param string $message
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function entityEmailFailed($message): void
|
private function entityEmailFailed(string $message = ''): void
|
||||||
{
|
{
|
||||||
$class = get_class($this->email_object->entity);
|
$class = get_class($this->email_object->entity);
|
||||||
|
|
||||||
|
@ -173,6 +173,11 @@ class QuickbooksService
|
|||||||
return $this->sdk->FindById($entity, $id);
|
return $this->sdk->FindById($entity, $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function query(string $query)
|
||||||
|
{
|
||||||
|
return $this->sdk->Query($query);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to determine if a sync is allowed in either direction
|
* Flag to determine if a sync is allowed in either direction
|
||||||
*
|
*
|
||||||
|
38
composer.lock
generated
38
composer.lock
generated
@ -2854,16 +2854,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "google/apiclient-services",
|
"name": "google/apiclient-services",
|
||||||
"version": "v0.373.0",
|
"version": "v0.374.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
||||||
"reference": "88ee17077a2048ba0b2c637754b599be0523fe36"
|
"reference": "5f6060df419f4f72dcc970197f9a9b1613cecc62"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/88ee17077a2048ba0b2c637754b599be0523fe36",
|
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/5f6060df419f4f72dcc970197f9a9b1613cecc62",
|
||||||
"reference": "88ee17077a2048ba0b2c637754b599be0523fe36",
|
"reference": "5f6060df419f4f72dcc970197f9a9b1613cecc62",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2892,9 +2892,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
||||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.373.0"
|
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.374.0"
|
||||||
},
|
},
|
||||||
"time": "2024-09-16T00:56:51+00:00"
|
"time": "2024-09-23T01:02:23+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "google/auth",
|
"name": "google/auth",
|
||||||
@ -7874,20 +7874,22 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nwidart/laravel-modules",
|
"name": "nwidart/laravel-modules",
|
||||||
"version": "v11.1.2",
|
"version": "v11.1.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nWidart/laravel-modules.git",
|
"url": "https://github.com/nWidart/laravel-modules.git",
|
||||||
"reference": "d275a5b9f7c329c505480750d354a7eef69fc42a"
|
"reference": "fb1f6bd7b168baaa6212dee678c18fc983d47ed4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/d275a5b9f7c329c505480750d354a7eef69fc42a",
|
"url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/fb1f6bd7b168baaa6212dee678c18fc983d47ed4",
|
||||||
"reference": "d275a5b9f7c329c505480750d354a7eef69fc42a",
|
"reference": "fb1f6bd7b168baaa6212dee678c18fc983d47ed4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"ext-dom": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
|
"ext-simplexml": "*",
|
||||||
"php": ">=8.2",
|
"php": ">=8.2",
|
||||||
"wikimedia/composer-merge-plugin": "^2.1"
|
"wikimedia/composer-merge-plugin": "^2.1"
|
||||||
},
|
},
|
||||||
@ -7945,7 +7947,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nWidart/laravel-modules/issues",
|
"issues": "https://github.com/nWidart/laravel-modules/issues",
|
||||||
"source": "https://github.com/nWidart/laravel-modules/tree/v11.1.2"
|
"source": "https://github.com/nWidart/laravel-modules/tree/v11.1.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -7957,7 +7959,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-09-20T08:45:18+00:00"
|
"time": "2024-09-22T20:04:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nyholm/psr7",
|
"name": "nyholm/psr7",
|
||||||
@ -9362,16 +9364,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpdoc-parser",
|
"name": "phpstan/phpdoc-parser",
|
||||||
"version": "1.30.1",
|
"version": "1.31.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||||
"reference": "51b95ec8670af41009e2b2b56873bad96682413e"
|
"reference": "249f15fb843bf240cf058372dad29e100cee6c17"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/51b95ec8670af41009e2b2b56873bad96682413e",
|
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/249f15fb843bf240cf058372dad29e100cee6c17",
|
||||||
"reference": "51b95ec8670af41009e2b2b56873bad96682413e",
|
"reference": "249f15fb843bf240cf058372dad29e100cee6c17",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9403,9 +9405,9 @@
|
|||||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.1"
|
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.31.0"
|
||||||
},
|
},
|
||||||
"time": "2024-09-07T20:13:05+00:00"
|
"time": "2024-09-22T11:32:18+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pragmarx/google2fa",
|
"name": "pragmarx/google2fa",
|
||||||
|
@ -22,6 +22,16 @@ return new class extends Migration
|
|||||||
$fields->secretKey = '';
|
$fields->secretKey = '';
|
||||||
$fields->testMode = false;
|
$fields->testMode = false;
|
||||||
$fields->gatewayId = '';
|
$fields->gatewayId = '';
|
||||||
|
$fields->amex = false;
|
||||||
|
$fields->ausbc = false;
|
||||||
|
$fields->discover = false;
|
||||||
|
$fields->japcb = false;
|
||||||
|
$fields->laser = false;
|
||||||
|
$fields->mastercard = true;
|
||||||
|
$fields->solo = false;
|
||||||
|
$fields->visa = true;
|
||||||
|
$fields->visa_white = false;
|
||||||
|
|
||||||
|
|
||||||
if($gateway = Gateway::find(64)){
|
if($gateway = Gateway::find(64)){
|
||||||
$gateway->fields = json_encode($fields);
|
$gateway->fields = json_encode($fields);
|
||||||
|
@ -89,7 +89,7 @@ class PaymentLibrariesSeeder extends Seeder
|
|||||||
['id' => 61, 'name' => 'PayPal Platform', 'provider' => 'PayPal_PPCP', 'key' => '80af24a6a691230bbec33e930ab40666', 'fields' => '{"testMode":false}'],
|
['id' => 61, 'name' => 'PayPal Platform', 'provider' => 'PayPal_PPCP', 'key' => '80af24a6a691230bbec33e930ab40666', 'fields' => '{"testMode":false}'],
|
||||||
['id' => 62, 'name' => 'BTCPay', 'provider' => 'BTCPay', 'key' => 'vpyfbmdrkqcicpkjqdusgjfluebftuva', 'fields' => '{"btcpayUrl":"", "apiKey":"", "storeId":"", "webhookSecret":""}'],
|
['id' => 62, 'name' => 'BTCPay', 'provider' => 'BTCPay', 'key' => 'vpyfbmdrkqcicpkjqdusgjfluebftuva', 'fields' => '{"btcpayUrl":"", "apiKey":"", "storeId":"", "webhookSecret":""}'],
|
||||||
['id' => 63, 'name' => 'Rotessa', 'is_offsite' => false, 'sort_order' => 22, 'provider' => 'Rotessa', 'key' => '91be24c7b792230bced33e930ac61676', 'fields' => '{"apiKey":"", "testMode":false}'],
|
['id' => 63, 'name' => 'Rotessa', 'is_offsite' => false, 'sort_order' => 22, 'provider' => 'Rotessa', 'key' => '91be24c7b792230bced33e930ac61676', 'fields' => '{"apiKey":"", "testMode":false}'],
|
||||||
['id' => 64, 'name' => 'CBA PowerBoard', 'is_offsite' => false, 'sort_order' => 26, 'provider' => 'CBAPowerBoard', 'key' => 'b67581d804dbad1743b61c57285142ad', 'fields' => '{"publicKey":"", "secretKey":"", "testMode":false, "gatewayId":""}'],
|
['id' => 64, 'name' => 'CBA PowerBoard', 'is_offsite' => false, 'sort_order' => 26, 'provider' => 'CBAPowerBoard', 'key' => 'b67581d804dbad1743b61c57285142ad', 'fields' => '{"publicKey":"", "secretKey":"", "testMode":false, "gatewayId":"", "amex":false, "ausbc":false, "discover":false, "japcb":false, "laser":false, "mastercard":true, "solo":false, "visa":true, "visa_white":false}'],
|
||||||
['id' => 65, 'name' => 'Blockonomics', 'is_offsite' => false, 'sort_order' => 27, 'provider' => 'Blockonomics', 'key' => 'wbhf02us6owgo7p4nfjd0ymssdshks4d', 'fields' => '{"apiKey":"", "callbackSecret":""}'],
|
['id' => 65, 'name' => 'Blockonomics', 'is_offsite' => false, 'sort_order' => 27, 'provider' => 'Blockonomics', 'key' => 'wbhf02us6owgo7p4nfjd0ymssdshks4d', 'fields' => '{"apiKey":"", "callbackSecret":""}'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
13
public/build/assets/powerboard-credit-card-f4852d3b.js
vendored
Normal file
13
public/build/assets/powerboard-credit-card-f4852d3b.js
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import{i as l,w as m}from"./wait-8f4ae121.js";/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/let u=!1;function y(){const t=document.querySelector("meta[name=public_key]"),e=document.querySelector("meta[name=gateway_id]"),r=document.querySelector("meta[name=environment]"),n=document.querySelector("meta[name=supported_cards]"),o=new cba.HtmlWidget("#widget",t==null?void 0:t.content,e==null?void 0:e.content);if(o.setEnv(r==null?void 0:r.content),o.useAutoResize(),n!=null&&n.content)try{const a=JSON.parse(n.content);o.setSupportedCardIcons(a,!0)}catch{}o.interceptSubmitForm("#stepone"),o.onFinishInsert('#server-response input[name="gateway_response"]',"payment_source"),o.setFormFields(["card_name*"]),o.reload();let d=document.getElementById("pay-now");return d.disabled=!1,d.querySelector("svg").classList.add("hidden"),d.querySelector("span").classList.remove("hidden"),document.querySelector('#server-response input[name="gateway_response"]').value="",o}function g(){var t,e,r;(t=document.querySelector("#widget"))==null||t.replaceChildren(),(e=document.querySelector("#widget"))==null||e.classList.remove("hidden"),(r=document.querySelector("#widget-3dsecure"))==null||r.replaceChildren()}function s(){var o,d;if(g(),!((o=document.querySelector("meta[name=gateway_id]"))==null?void 0:o.content)){let a=document.getElementById("pay-now");a.disabled=!0,a.querySelector("svg").classList.remove("hidden"),a.querySelector("span").classList.add("hidden"),document.getElementById("errors").textContent="Gateway not found or verified",document.getElementById("errors").hidden=!1}const e=y();e.on("finish",()=>{document.getElementById("errors").hidden=!0,p()}),e.on("submit",function(a){document.getElementById("errors").hidden=!0});let r=document.getElementById("pay-now");r.addEventListener("click",()=>{const a=document.getElementById("widget");if(e.getValidationState(),!e.isValidForm()&&a.offsetParent!==null){r.disabled=!1,r.querySelector("svg").classList.add("hidden"),r.querySelector("span").classList.remove("hidden");return}r.disabled=!0,r.querySelector("svg").classList.remove("hidden"),r.querySelector("span").classList.add("hidden");let c=document.querySelector("input[name=token-billing-checkbox]:checked");c&&(document.getElementById("store_card").value=c.value),a.offsetParent!==null?document.getElementById("stepone_submit").click():document.getElementById("server-response").submit()}),document.getElementById("toggle-payment-with-credit-card").addEventListener("click",a=>{var i;document.getElementById("widget").classList.remove("hidden"),document.getElementById("save-card--container").style.display="grid",document.querySelector("input[name=token]").value="",(i=document.querySelector("#powerboard-payment-container"))==null||i.classList.remove("hidden")}),Array.from(document.getElementsByClassName("toggle-payment-with-token")).forEach(a=>a.addEventListener("click",c=>{var i;document.getElementById("widget").classList.add("hidden"),document.getElementById("save-card--container").style.display="none",document.querySelector("input[name=token]").value=c.target.dataset.token,(i=document.querySelector("#powerboard-payment-container"))==null||i.classList.add("hidden")}));const n=document.querySelector('input[name="payment-type"]');n&&n.click(),u&&((d=document.getElementById("toggle-payment-with-credit-card"))==null||d.click())}async function p(){try{const t=await h();if(!t||!t.status||t.status==="not_authenticated"||t==="not_authenticated")throw u=!0,s(),new Error("There was an issue authenticating this payment method.");if(t.status==="authentication_not_supported"){document.querySelector('input[name="browser_details"]').value=null,document.querySelector('input[name="charge"]').value=JSON.stringify(t);let n=document.querySelector("input[name=token-billing-checkbox]:checked");return n&&(document.getElementById("store_card").value=n.value),document.getElementById("server-response").submit()}const e=new cba.Canvas3ds("#widget-3dsecure",t._3ds.token);e.load(),document.getElementById("widget").classList.add("hidden"),e.on("chargeAuthSuccess",function(n){document.querySelector('input[name="browser_details"]').value=null,document.querySelector('input[name="charge"]').value=JSON.stringify(n);let o=document.querySelector("input[name=token-billing-checkbox]:checked");o&&(document.getElementById("store_card").value=o.value),document.getElementById("server-response").submit()}),e.on("chargeAuthReject",function(n){document.getElementById("errors").textContent="Sorry, your transaction could not be processed...",document.getElementById("errors").hidden=!1,u=!0,s()}),e.load()}catch(t){const e=t.message??"Unknown error.";document.getElementById("errors").textContent=`Sorry, your transaction could not be processed...
|
||||||
|
|
||||||
|
${e}`,document.getElementById("errors").hidden=!1,u=!0,s()}}async function h(){const t={name:navigator.userAgent.substring(0,100),java_enabled:navigator.javaEnabled()?"true":"false",language:navigator.language||navigator.userLanguage,screen_height:window.screen.height.toString(),screen_width:window.screen.width.toString(),time_zone:(new Date().getTimezoneOffset()*-1).toString(),color_depth:window.screen.colorDepth.toString()};document.querySelector('input[name="browser_details"]').value=JSON.stringify(t);const e=JSON.stringify(Object.fromEntries(new FormData(document.getElementById("server-response")))),r=document.querySelector("meta[name=payments_route]");try{const n=await fetch(r.content,{method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",Accept:"application/json","X-CSRF-Token":document.querySelector('meta[name="csrf-token"]').content},body:e});return n.ok?await n.json():await n.json().then(o=>{throw new Error(o.message??"Unknown error.")})}catch(n){document.getElementById("errors").textContent=`Sorry, your transaction could not be processed...
|
||||||
|
|
||||||
|
${n.message}`,document.getElementById("errors").hidden=!1,u=!0,s()}}l()?s():m("#powerboard-credit-card-payment").then(()=>s());
|
@ -1,13 +0,0 @@
|
|||||||
import{i as l,w as m}from"./wait-8f4ae121.js";/**
|
|
||||||
* Invoice Ninja (https://invoiceninja.com).
|
|
||||||
*
|
|
||||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @license https://www.elastic.co/licensing/elastic-license
|
|
||||||
*/let i=!1;function y(){const n=document.querySelector("meta[name=public_key]"),t=document.querySelector("meta[name=gateway_id]"),r=document.querySelector("meta[name=environment]"),e=new cba.HtmlWidget("#widget",n==null?void 0:n.content,t==null?void 0:t.content);e.setEnv(r==null?void 0:r.content),e.useAutoResize(),e.interceptSubmitForm("#stepone"),e.onFinishInsert('#server-response input[name="gateway_response"]',"payment_source"),e.setFormFields(["card_name*"]),e.reload();let o=document.getElementById("pay-now");return o.disabled=!1,o.querySelector("svg").classList.add("hidden"),o.querySelector("span").classList.remove("hidden"),document.querySelector('#server-response input[name="gateway_response"]').value="",e}function g(){var n,t,r;(n=document.querySelector("#widget"))==null||n.replaceChildren(),(t=document.querySelector("#widget"))==null||t.classList.remove("hidden"),(r=document.querySelector("#widget-3dsecure"))==null||r.replaceChildren()}function a(){var o,u;if(g(),!((o=document.querySelector("meta[name=gateway_id]"))==null?void 0:o.content)){let d=document.getElementById("pay-now");d.disabled=!0,d.querySelector("svg").classList.remove("hidden"),d.querySelector("span").classList.add("hidden"),document.getElementById("errors").textContent="Gateway not found or verified",document.getElementById("errors").hidden=!1}const t=y();t.on("finish",()=>{document.getElementById("errors").hidden=!0,p()}),t.on("submit",function(d){document.getElementById("errors").hidden=!0});let r=document.getElementById("pay-now");r.addEventListener("click",()=>{const d=document.getElementById("widget");if(t.getValidationState(),!t.isValidForm()&&d.offsetParent!==null){r.disabled=!1,r.querySelector("svg").classList.add("hidden"),r.querySelector("span").classList.remove("hidden");return}r.disabled=!0,r.querySelector("svg").classList.remove("hidden"),r.querySelector("span").classList.add("hidden");let s=document.querySelector("input[name=token-billing-checkbox]:checked");s&&(document.getElementById("store_card").value=s.value),d.offsetParent!==null?document.getElementById("stepone_submit").click():document.getElementById("server-response").submit()}),document.getElementById("toggle-payment-with-credit-card").addEventListener("click",d=>{var c;document.getElementById("widget").classList.remove("hidden"),document.getElementById("save-card--container").style.display="grid",document.querySelector("input[name=token]").value="",(c=document.querySelector("#powerboard-payment-container"))==null||c.classList.remove("hidden")}),Array.from(document.getElementsByClassName("toggle-payment-with-token")).forEach(d=>d.addEventListener("click",s=>{var c;document.getElementById("widget").classList.add("hidden"),document.getElementById("save-card--container").style.display="none",document.querySelector("input[name=token]").value=s.target.dataset.token,(c=document.querySelector("#powerboard-payment-container"))==null||c.classList.add("hidden")}));const e=document.querySelector('input[name="payment-type"]');e&&e.click(),i&&((u=document.getElementById("toggle-payment-with-credit-card"))==null||u.click())}async function p(){try{const n=await h();if(!n||!n.status||n.status==="not_authenticated"||n==="not_authenticated")throw i=!0,a(),new Error("There was an issue authenticating this payment method.");if(n.status==="authentication_not_supported"){document.querySelector('input[name="browser_details"]').value=null,document.querySelector('input[name="charge"]').value=JSON.stringify(n);let e=document.querySelector("input[name=token-billing-checkbox]:checked");return e&&(document.getElementById("store_card").value=e.value),document.getElementById("server-response").submit()}const t=new cba.Canvas3ds("#widget-3dsecure",n._3ds.token);t.load(),document.getElementById("widget").classList.add("hidden"),t.on("chargeAuthSuccess",function(e){document.querySelector('input[name="browser_details"]').value=null,document.querySelector('input[name="charge"]').value=JSON.stringify(e);let o=document.querySelector("input[name=token-billing-checkbox]:checked");o&&(document.getElementById("store_card").value=o.value),document.getElementById("server-response").submit()}),t.on("chargeAuthReject",function(e){document.getElementById("errors").textContent="Sorry, your transaction could not be processed...",document.getElementById("errors").hidden=!1,i=!0,a()}),t.load()}catch(n){const t=n.message??"Unknown error.";document.getElementById("errors").textContent=`Sorry, your transaction could not be processed...
|
|
||||||
|
|
||||||
${t}`,document.getElementById("errors").hidden=!1,i=!0,a()}}async function h(){const n={name:navigator.userAgent.substring(0,100),java_enabled:navigator.javaEnabled()?"true":"false",language:navigator.language||navigator.userLanguage,screen_height:window.screen.height.toString(),screen_width:window.screen.width.toString(),time_zone:(new Date().getTimezoneOffset()*-1).toString(),color_depth:window.screen.colorDepth.toString()};document.querySelector('input[name="browser_details"]').value=JSON.stringify(n);const t=JSON.stringify(Object.fromEntries(new FormData(document.getElementById("server-response")))),r=document.querySelector("meta[name=payments_route]");try{const e=await fetch(r.content,{method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",Accept:"application/json","X-CSRF-Token":document.querySelector('meta[name="csrf-token"]').content},body:t});return e.ok?await e.json():await e.json().then(o=>{throw new Error(o.message??"Unknown error.")})}catch(e){document.getElementById("errors").textContent=`Sorry, your transaction could not be processed...
|
|
||||||
|
|
||||||
${e.message}`,document.getElementById("errors").hidden=!1,i=!0,a()}}l()?a():m("#powerboard-credit-card-payment").then(()=>a());
|
|
@ -158,7 +158,7 @@
|
|||||||
"src": "resources/js/clients/payments/paytrace-credit-card.js"
|
"src": "resources/js/clients/payments/paytrace-credit-card.js"
|
||||||
},
|
},
|
||||||
"resources/js/clients/payments/powerboard-credit-card.js": {
|
"resources/js/clients/payments/powerboard-credit-card.js": {
|
||||||
"file": "assets/powerboard-credit-card-f5f23291.js",
|
"file": "assets/powerboard-credit-card-f4852d3b.js",
|
||||||
"imports": [
|
"imports": [
|
||||||
"_wait-8f4ae121.js"
|
"_wait-8f4ae121.js"
|
||||||
],
|
],
|
||||||
|
@ -16,6 +16,7 @@ function setup() {
|
|||||||
const publicKey = document.querySelector('meta[name=public_key]');
|
const publicKey = document.querySelector('meta[name=public_key]');
|
||||||
const gatewayId = document.querySelector('meta[name=gateway_id]');
|
const gatewayId = document.querySelector('meta[name=gateway_id]');
|
||||||
const env = document.querySelector('meta[name=environment]');
|
const env = document.querySelector('meta[name=environment]');
|
||||||
|
const supportedCards = document.querySelector('meta[name=supported_cards]');
|
||||||
|
|
||||||
const widget = new cba.HtmlWidget(
|
const widget = new cba.HtmlWidget(
|
||||||
'#widget',
|
'#widget',
|
||||||
@ -25,6 +26,15 @@ function setup() {
|
|||||||
|
|
||||||
widget.setEnv(env?.content);
|
widget.setEnv(env?.content);
|
||||||
widget.useAutoResize();
|
widget.useAutoResize();
|
||||||
|
|
||||||
|
if (supportedCards?.content) {
|
||||||
|
try {
|
||||||
|
const supportedCardsArray = JSON.parse(supportedCards.content);
|
||||||
|
widget.setSupportedCardIcons(supportedCardsArray, true);
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
widget.interceptSubmitForm('#stepone');
|
widget.interceptSubmitForm('#stepone');
|
||||||
widget.onFinishInsert(
|
widget.onFinishInsert(
|
||||||
'#server-response input[name="gateway_response"]',
|
'#server-response input[name="gateway_response"]',
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<meta name="gateway_id" content="{{ $gateway_id }}" />
|
<meta name="gateway_id" content="{{ $gateway_id }}" />
|
||||||
<meta name="environment" content="{{ $environment }}">
|
<meta name="environment" content="{{ $environment }}">
|
||||||
<meta name="payments_route" content="{{ route('client.payments.response') }}" />
|
<meta name="payments_route" content="{{ route('client.payments.response') }}" />
|
||||||
|
<meta name="supported_cards" content="{{ json_encode($supported_cards) }}" />
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('gateway_content')
|
@section('gateway_content')
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<meta name="gateway_id" content="{{ $gateway_id }}" />
|
<meta name="gateway_id" content="{{ $gateway_id }}" />
|
||||||
<meta name="environment" content="{{ $environment }}">
|
<meta name="environment" content="{{ $environment }}">
|
||||||
<meta name="payments_route" content="{{ route('client.payments.response') }}" />
|
<meta name="payments_route" content="{{ route('client.payments.response') }}" />
|
||||||
|
<meta name="supported_cards" content="{{ json_encode($supported_cards) }}" />
|
||||||
|
|
||||||
<form action="javascript:void(0);" id="stepone">
|
<form action="javascript:void(0);" id="stepone">
|
||||||
<input type="hidden" name="gateway_response">
|
<input type="hidden" name="gateway_response">
|
||||||
|
@ -52,13 +52,15 @@ class QuickbooksTest extends TestCase
|
|||||||
$this->faker = \Faker\Factory::create();
|
$this->faker = \Faker\Factory::create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function createQbProduct()
|
public function createQbProduct()
|
||||||
{
|
{
|
||||||
$service_product = Product::factory()->create([
|
$service_product = Product::factory()->create([
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
'user_id' => $this->company->owner()->id,
|
'user_id' => $this->company->owner()->id,
|
||||||
'notes' => $this->faker->sentence(),
|
'notes' => $this->faker->sentence(),
|
||||||
'product_key' => $this->faker->word(63),
|
'product_key' => \Illuminate\Support\Str::random(64),
|
||||||
'tax_id' => 2,
|
'tax_id' => 2,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -67,7 +69,7 @@ class QuickbooksTest extends TestCase
|
|||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
'user_id' => $this->company->owner()->id,
|
'user_id' => $this->company->owner()->id,
|
||||||
'notes' => $this->faker->sentence(),
|
'notes' => $this->faker->sentence(),
|
||||||
'product_key' => $this->faker->word(63),
|
'product_key' => \Illuminate\Support\Str::random(64),
|
||||||
'tax_id' => 1,
|
'tax_id' => 1,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -135,11 +137,17 @@ class QuickbooksTest extends TestCase
|
|||||||
$client = Client::factory()->create([
|
$client = Client::factory()->create([
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
'user_id' => $this->company->owner()->id,
|
'user_id' => $this->company->owner()->id,
|
||||||
'address1' => $this->faker->address(),
|
'address1' => "10369 Ashton Avenue",
|
||||||
'city' => $this->faker->city(),
|
'address2' => '',
|
||||||
'state' => $this->faker->state(),
|
'city' => "Beverley Hills",
|
||||||
'postal_code' => $this->faker->postcode(),
|
'state' => "California",
|
||||||
|
'postal_code' => "90210",
|
||||||
'country_id' => 840,
|
'country_id' => 840,
|
||||||
|
'shipping_address1' => "10369 Ashton Avenue",
|
||||||
|
'address2' => '',
|
||||||
|
'shipping_city' => "Beverley Hills",
|
||||||
|
'shipping_state' => "California",
|
||||||
|
'shipping_postal_code' => "90210",
|
||||||
'shipping_country_id' => 840,
|
'shipping_country_id' => 840,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -213,9 +221,16 @@ class QuickbooksTest extends TestCase
|
|||||||
//create ninja invoice
|
//create ninja invoice
|
||||||
$qb_invoice = $this->createQbInvoice($customer);
|
$qb_invoice = $this->createQbInvoice($customer);
|
||||||
|
|
||||||
|
|
||||||
$this->assertNotNull($qb_invoice);
|
$this->assertNotNull($qb_invoice);
|
||||||
|
|
||||||
nlog($qb_invoice);
|
// sleep(5);
|
||||||
|
|
||||||
|
// $updatedInvoice = $this->qb->sdk->FindById('invoice', $qb_invoice->Id->value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
nlog($updatedInvoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCreateCustomerInQb()
|
public function testCreateCustomerInQb()
|
||||||
@ -262,6 +277,8 @@ class QuickbooksTest extends TestCase
|
|||||||
$item_product->quantity = 1;
|
$item_product->quantity = 1;
|
||||||
$item_product->cost = $non_inventory_product->price;
|
$item_product->cost = $non_inventory_product->price;
|
||||||
$item_product->line_total = $non_inventory_product->price;
|
$item_product->line_total = $non_inventory_product->price;
|
||||||
|
$item_product->tax_name1 = 'CA Sales Tax';
|
||||||
|
$item_product->tax_rate1 = 8;
|
||||||
$item_product->type_id = '1';
|
$item_product->type_id = '1';
|
||||||
|
|
||||||
$item_service = new InvoiceItem();
|
$item_service = new InvoiceItem();
|
||||||
@ -303,6 +320,12 @@ class QuickbooksTest extends TestCase
|
|||||||
// $this->assertEquals(30, $i->balance);
|
// $this->assertEquals(30, $i->balance);
|
||||||
|
|
||||||
$line_items = [];
|
$line_items = [];
|
||||||
|
|
||||||
|
// $taxDetail = [
|
||||||
|
// "TotalTax" => 0,
|
||||||
|
// "TaxLine" => []
|
||||||
|
// ];
|
||||||
|
|
||||||
$line_num = 1;
|
$line_num = 1;
|
||||||
|
|
||||||
foreach($i->line_items as $line_item)
|
foreach($i->line_items as $line_item)
|
||||||
@ -327,10 +350,68 @@ class QuickbooksTest extends TestCase
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
'Description' => $line_item->notes,
|
'Description' => $line_item->notes,
|
||||||
|
|
||||||
'Amount' => $line_item->line_total,
|
'Amount' => $line_item->line_total,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// if($line_item->tax_rate1 > 0)
|
||||||
|
// {
|
||||||
|
// $tax_line_detail = [
|
||||||
|
// "Amount" => $line_item->tax_amount,
|
||||||
|
// "DetailType" => "TaxLineDetail",
|
||||||
|
// "TaxLineDetail" => [
|
||||||
|
// "TaxRateRef" => [
|
||||||
|
// "value" => $line_item->tax_rate1,
|
||||||
|
// "name" => $line_item->tax_name1,
|
||||||
|
// ],
|
||||||
|
// "PercentBased" => true,
|
||||||
|
// "TaxPercent" => $line_item->tax_rate1,
|
||||||
|
// "NetAmountTaxable" => $line_item->line_total,
|
||||||
|
// ]
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// $taxDetail['TaxLine'][] = $tax_line_detail;
|
||||||
|
// $taxDetail['TotalTax'] += $line_item->tax_amount;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if ($line_item->tax_rate2 > 0) {
|
||||||
|
// $tax_line_detail = [
|
||||||
|
// "Amount" => $line_item->tax_amount,
|
||||||
|
// "DetailType" => "TaxLineDetail",
|
||||||
|
// "TaxLineDetail" => [
|
||||||
|
// "TaxRateRef" => [
|
||||||
|
// "value" => $line_item->tax_rate2,
|
||||||
|
// "name" => $line_items->tax_name2,
|
||||||
|
// ],
|
||||||
|
// "PercentBased" => true,
|
||||||
|
// "TaxPercent" => $line_item->tax_rate2,
|
||||||
|
// "NetAmountTaxable" => $line_item->line_total,
|
||||||
|
// ]
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// $taxDetail['TaxLine'][] = $tax_line_detail;
|
||||||
|
// $taxDetail['TotalTax'] += $line_item->tax_amount;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if ($line_item->tax_rate3 > 0) {
|
||||||
|
// $tax_line_detail = [
|
||||||
|
// "Amount" => $line_item->tax_amount,
|
||||||
|
// "DetailType" => "TaxLineDetail",
|
||||||
|
// "TaxLineDetail" => [
|
||||||
|
// "TaxRateRef" => [
|
||||||
|
// "value" => $line_item->tax_name3
|
||||||
|
// ],
|
||||||
|
// "PercentBased" => true,
|
||||||
|
// "TaxPercent" => $line_item->tax_rate3,
|
||||||
|
// "NetAmountTaxable" => $line_item->line_total,
|
||||||
|
// ]
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// $taxDetail['TaxLine'][] = $tax_line_detail;
|
||||||
|
// $taxDetail['TotalTax'] += $line_item->tax_amount;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$line_num++;
|
$line_num++;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -347,15 +428,19 @@ class QuickbooksTest extends TestCase
|
|||||||
"DueDate" => $i->due_date,
|
"DueDate" => $i->due_date,
|
||||||
"TotalAmt" => $i->amount,
|
"TotalAmt" => $i->amount,
|
||||||
"DocNumber" => $i->number,
|
"DocNumber" => $i->number,
|
||||||
"ApplyTaxAfterDiscount" => false,
|
"ApplyTaxAfterDiscount" => true,
|
||||||
"GlobalTaxCalculation" => "TaxExcluded", // This tells QuickBooks to calculate taxes
|
"PrintStatus" => "NeedToPrint",
|
||||||
"TxnTaxDetail" => [
|
"EmailStatus" => "NotSet",
|
||||||
"UseAutomatedSalesTax" => true,
|
"GlobalTaxCalculation" => "TaxExcluded",
|
||||||
|
// "ApplyTaxAfterDiscount" => false,
|
||||||
|
// "TxnTaxDetail" => $taxDetail,
|
||||||
|
// "TxnTaxDetail" => [
|
||||||
|
// "UseAutomatedSalesTax" => true,
|
||||||
// "TxnTaxCodeRef" => [
|
// "TxnTaxCodeRef" => [
|
||||||
// "value" => "TAX" // Use the appropriate tax code for your QuickBooks account
|
// "value" => "SALES_TAX_STUB" // Use the appropriate tax code for your QuickBooks account
|
||||||
// "DefaultTaxRateRef" => [
|
// "DefaultTaxRateRef" => [
|
||||||
|
// ],
|
||||||
// ]
|
// ]
|
||||||
]
|
|
||||||
// "Note" => $this->invoice->public_notes,
|
// "Note" => $this->invoice->public_notes,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -62,6 +62,38 @@ class PaymentTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNullPaymentAmounts()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'amount' => "null",
|
||||||
|
'client_id' => "null",
|
||||||
|
'invoices' => [
|
||||||
|
[
|
||||||
|
'invoice_id' => $this->invoice->hashed_id,
|
||||||
|
'amount' => "null",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'credits' => [
|
||||||
|
[
|
||||||
|
'credit_id' => $this->invoice->hashed_id,
|
||||||
|
'amount' => "null",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'date' => '2020/12/11',
|
||||||
|
'idempotency_key' => 'xx',
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/payments/', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testIdempotencyTrigger()
|
public function testIdempotencyTrigger()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user