Merge pull request #7968 from turbo124/v5-develop

Fixes for blank client addresses in Swiss QR Codes
This commit is contained in:
David Bomba 2022-11-22 16:23:58 +11:00 committed by GitHub
commit c70ec97450
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 153 additions and 31 deletions

View File

@ -1 +1 @@
5.5.41 5.5.42

View File

@ -87,7 +87,8 @@ class AccountTransformer implements AccountTransformerInterface
return [ return [
'id' => $account->id, 'id' => $account->id,
'account_type' => $account->CONTAINER, 'account_type' => $account->CONTAINER,
'account_name' => $account->accountName, // 'account_name' => $account->accountName,
'account_name' => property_exists($account, 'accountName') ? $account->accountName : $account->nickname,
'account_status' => $account->accountStatus, 'account_status' => $account->accountStatus,
'account_number' => property_exists($account, 'accountNumber') ? '**** ' . substr($account?->accountNumber, -7) : '', 'account_number' => property_exists($account, 'accountNumber') ? '**** ' . substr($account?->accountNumber, -7) : '',
'provider_account_id' => $account->providerAccountId, 'provider_account_id' => $account->providerAccountId,

View File

@ -49,9 +49,12 @@ class EpcQrGenerator
$this->validateFields(); $this->validateFields();
try { try {
$qr = $writer->writeString($this->encodeMessage()); $qr = $writer->writeString($this->encodeMessage(), 'utf-8');
} }
catch(BaconQrCode\Exception\WriterException $e){ catch(\Throwable $e){
return '';
}
catch(\Exception $e){
return ''; return '';
} }
return "<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'> return "<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>

View File

@ -87,10 +87,10 @@ class SwissQrGenerator
$qrBill->setUltimateDebtor( $qrBill->setUltimateDebtor(
QrBill\DataGroup\Element\StructuredAddress::createWithStreet( QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
substr($this->client->present()->name(), 0 , 70), substr($this->client->present()->name(), 0 , 70),
$this->client->address1 ? substr($this->client->address1, 0 , 70) : '', $this->client->address1 ? substr($this->client->address1, 0 , 70) : '_',
$this->client->address2 ? substr($this->client->address2, 0 , 16) : '', $this->client->address2 ? substr($this->client->address2, 0 , 16) : '_',
$this->client->postal_code ? substr($this->client->postal_code, 0, 16) : '', $this->client->postal_code ? substr($this->client->postal_code, 0, 16) : '_',
$this->client->city ? substr($this->client->city, 0, 35) : '', $this->client->city ? substr($this->client->city, 0, 35) : '_',
'CH' 'CH'
)); ));

View File

@ -293,7 +293,7 @@ class CompanyExport implements ShouldQueue
$this->export_data['payments'] = $this->company->payments()->orderBy('number', 'DESC')->cursor()->map(function ($payment){ $this->export_data['payments'] = $this->company->payments()->orderBy('number', 'DESC')->cursor()->map(function ($payment){
$payment = $this->transformBasicEntities($payment); $payment = $this->transformBasicEntities($payment);
$payment = $this->transformArrayOfKeys($payment, ['client_id','project_id', 'vendor_id', 'client_contact_id', 'invitation_id', 'company_gateway_id']); $payment = $this->transformArrayOfKeys($payment, ['client_id','project_id', 'vendor_id', 'client_contact_id', 'invitation_id', 'company_gateway_id', 'transaction_id']);
$payment->paymentables = $this->transformPaymentable($payment); $payment->paymentables = $this->transformPaymentable($payment);
@ -456,7 +456,6 @@ class CompanyExport implements ShouldQueue
})->all(); })->all();
$this->export_data['purchase_order_invitations'] = PurchaseOrderInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($purchase_order){ $this->export_data['purchase_order_invitations'] = PurchaseOrderInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($purchase_order){
$purchase_order = $this->transformArrayOfKeys($purchase_order, ['company_id', 'user_id', 'vendor_contact_id', 'purchase_order_id']); $purchase_order = $this->transformArrayOfKeys($purchase_order, ['company_id', 'user_id', 'vendor_contact_id', 'purchase_order_id']);
@ -466,6 +465,21 @@ class CompanyExport implements ShouldQueue
})->all(); })->all();
$this->export_data['bank_integrations'] = $this->company->bank_integrations()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration){
$bank_integration = $this->transformArrayOfKeys($bank_integration, ['account_id','company_id', 'user_id']);
return $bank_integration->makeVisible(['id','user_id','company_id','account_id']);
})->all();
$this->export_data['bank_transactions'] = $this->company->bank_transactions()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction){
$bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','category_id','ninja_category_id','vendor_id']);
return $bank_transaction->makeVisible(['id','user_id','company_id']);
})->all();
//write to tmp and email to owner(); //write to tmp and email to owner();
@ -516,9 +530,6 @@ class CompanyExport implements ShouldQueue
$file_name = date('Y-m-d').'_'.str_replace([" ", "/"],["_",""], $this->company->present()->name() . '_' . $this->company->company_key .'.zip'); $file_name = date('Y-m-d').'_'.str_replace([" ", "/"],["_",""], $this->company->present()->name() . '_' . $this->company->company_key .'.zip');
$path = 'backups'; $path = 'backups';
// if(!Storage::disk(config('filesystems.default'))->exists($path))
// Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775);
$zip_path = public_path('storage/backups/'.$file_name); $zip_path = public_path('storage/backups/'.$file_name);
$zip = new \ZipArchive(); $zip = new \ZipArchive();

View File

@ -24,6 +24,8 @@ use App\Mail\Import\CompanyImportFailure;
use App\Mail\Import\ImportCompleted; use App\Mail\Import\ImportCompleted;
use App\Models\Activity; use App\Models\Activity;
use App\Models\Backup; use App\Models\Backup;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Models\Client; use App\Models\Client;
use App\Models\ClientContact; use App\Models\ClientContact;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
@ -142,15 +144,16 @@ class CompanyImport implements ShouldQueue
'expenses', 'expenses',
'tasks', 'tasks',
'payments', 'payments',
// 'activities',
// 'backups',
'company_ledger', 'company_ledger',
'designs', 'designs',
'documents', 'documents',
'webhooks', 'webhooks',
'system_logs', 'system_logs',
'purchase_orders', 'purchase_orders',
'purchase_order_invitations' 'purchase_order_invitations',
'bank_integrations',
'bank_transactions',
'payments',
]; ];
private $company_properties = [ private $company_properties = [
@ -527,6 +530,37 @@ class CompanyImport implements ShouldQueue
} }
private function import_bank_integrations()
{
$this->genericImport(BankIntegration::class,
['assigned_user_id','account_id', 'company_id', 'id', 'hashed_id'],
[
['users' => 'user_id'],
],
'bank_integrations',
'description');
return $this;
}
private function import_bank_transactions()
{
$this->genericImport(BankTransaction::class,
['assigned_user_id','company_id', 'id', 'hashed_id', 'user_id'],
[
['users' => 'user_id'],
['expenses' => 'expense_id'],
['vendors' => 'vendor_id'],
['expense_categories' => 'ninja_category_id'],
['expense_categories' => 'category_id'],
['bank_integrations' => 'bank_integration_id']
],
'bank_transactions',
null);
return $this;
}
private function import_recurring_expenses() private function import_recurring_expenses()
{ {
//unset / transforms / object_property / match_key //unset / transforms / object_property / match_key
@ -979,6 +1013,7 @@ class CompanyImport implements ShouldQueue
['vendors' => 'vendor_id'], ['vendors' => 'vendor_id'],
['invoice_invitations' => 'invitation_id'], ['invoice_invitations' => 'invitation_id'],
['company_gateways' => 'company_gateway_id'], ['company_gateways' => 'company_gateway_id'],
['bank_transactions' => 'transaction_id'],
], ],
'payments', 'payments',
'number'); 'number');
@ -1569,6 +1604,28 @@ class CompanyImport implements ShouldQueue
$obj_array, $obj_array,
); );
} }
elseif($class == 'App\Models\BankIntegration'){
$new_obj = new BankIntegration();
$new_obj->company_id = $this->company->id;
$new_obj->account_id = $this->account->id;
$new_obj->fill($obj_array);
$new_obj->save(['timestamps' => false]);
}
elseif($class == 'App\Models\BankTransaction'){
$new_obj = new BankTransaction();
$new_obj->company_id = $this->company->id;
$obj_array['invoice_ids'] = collect(explode(",",$obj_array['invoice_ids']))->map(function ($id) {
return $this->transformId('invoices', $id);
})->map(function ($encodeable){
return $this->encodePrimaryKey($encodeable);
})->implode(",");
$new_obj->fill($obj_array);
$new_obj->save(['timestamps' => false]);
}
else{ else{
$new_obj = $class::withTrashed()->firstOrNew( $new_obj = $class::withTrashed()->firstOrNew(
[$match_key => $obj->{$match_key}, 'company_id' => $this->company->id], [$match_key => $obj->{$match_key}, 'company_id' => $this->company->id],

View File

@ -111,7 +111,10 @@ class PayPal
'paymentMethodNonce' => $gateway_response->nonce, 'paymentMethodNonce' => $gateway_response->nonce,
]); ]);
return $payment_method->paymentMethod->token; if($payment_method->success)
return $payment_method->paymentMethod->token;
else
throw new PaymentFailed(property_exists($payment_method, 'message') ? $payment_method->message : 'Undefined error storing payment token.', 0);
} }
/** /**

View File

@ -306,10 +306,53 @@ class CheckoutComPaymentDriver extends BaseDriver
try { try {
$response = $this->gateway->getCustomersClient()->create($request); $response = $this->gateway->getCustomersClient()->create($request);
} catch (\Exception $e) {
// API error
throw new PaymentFailed($e->getMessage(), $e->getCode());
} }
catch (CheckoutApiException $e) {
// API error
$request_id = $e->request_id;
$http_status_code = $e->http_status_code;
$error_details = $e->error_details;
if(is_array($error_details)) {
$error_details = end($e->error_details['error_codes']);
}
$human_exception = $error_details ? new \Exception($error_details, 400) : $e;
throw new PaymentFailed($human_exception);
} catch (CheckoutArgumentException $e) {
// Bad arguments
$error_details = $e->error_details;
if(is_array($error_details)) {
$error_details = end($e->error_details['error_codes']);
}
$human_exception = $error_details ? new \Exception($error_details, 400) : $e;
throw new PaymentFailed($human_exception);
} catch (CheckoutAuthorizationException $e) {
// Bad Invalid authorization
$error_details = $e->error_details;
if(is_array($error_details)) {
$error_details = end($e->error_details['error_codes']);
}
$human_exception = $error_details ? new \Exception($error_details, 400) : $e;
throw new PaymentFailed($human_exception);
}
// catch (\Exception $e) {
// // API error
// throw new PaymentFailed($e->getMessage(), $e->getCode());
// }
return $response; return $response;
} }

View File

@ -104,7 +104,6 @@ class DeletePayment
$client = $this->payment $client = $this->payment
->client ->client
->fresh()
->service() ->service()
->updateBalance($net_deletable) ->updateBalance($net_deletable)
->save(); ->save();
@ -136,9 +135,8 @@ class DeletePayment
}); });
} }
$client = $this->payment->client->fresh(); $this->payment
->client
$client
->service() ->service()
->updatePaidToDate(($this->payment->amount - $this->payment->refunded) * -1) ->updatePaidToDate(($this->payment->amount - $this->payment->refunded) * -1)
->save(); ->save();
@ -146,7 +144,7 @@ class DeletePayment
$transaction = [ $transaction = [
'invoice' => [], 'invoice' => [],
'payment' => [], 'payment' => [],
'client' => $client->transaction_event(), 'client' => $this->payment->client->transaction_event(),
'credit' => [], 'credit' => [],
'metadata' => [], 'metadata' => [],
]; ];

View File

@ -62,12 +62,14 @@ class UpdateInvoicePayment
$paid_amount = $paid_invoice->amount; $paid_amount = $paid_invoice->amount;
} }
$client->service()->updateBalanceAndPaidToDate($paid_amount*-1, $paid_amount); $client->service()->updatePaidToDate($paid_amount); //always use the payment->amount
/* Need to determine here is we have an OVER payment - if YES only apply the max invoice amount */ /* Need to determine here is we have an OVER payment - if YES only apply the max invoice amount */
if($paid_amount > $invoice->partial && $paid_amount > $invoice->balance) if($paid_amount > $invoice->partial && $paid_amount > $invoice->balance)
$paid_amount = $invoice->balance; $paid_amount = $invoice->balance;
$client->service()->updateBalance($paid_amount*-1); //only ever use the amount applied to the invoice
/*Improve performance here - 26-01-2022 - also change the order of events for invoice first*/ /*Improve performance here - 26-01-2022 - also change the order of events for invoice first*/
//caution what if we amount paid was less than partial - we wipe it! //caution what if we amount paid was less than partial - we wipe it!
$invoice->balance -= $paid_amount; $invoice->balance -= $paid_amount;

View File

@ -95,10 +95,14 @@ class SystemHealth
if(strlen(config('ninja.currency_converter_api_key')) == 0){ if(strlen(config('ninja.currency_converter_api_key')) == 0){
try{
$cs = DB::table('clients') $cs = DB::table('clients')
->select('settings->currency_id as id') ->select('settings->currency_id as id')
->get(); ->get();
}
catch(\Exception $e){
return true; //fresh installs, there may be no DB connection, nor migrations could have run yet.
}
$currency_count = $cs->unique('id')->filter(function ($value){ $currency_count = $cs->unique('id')->filter(function ($value){
return !is_null($value->id); return !is_null($value->id);

View File

@ -14,8 +14,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true), 'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => '5.5.41', 'app_version' => '5.5.42',
'app_tag' => '5.5.41', 'app_tag' => '5.5.42',
'minimum_client_version' => '5.0.16', 'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1', 'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', ''), 'api_secret' => env('API_SECRET', ''),

View File

@ -257,7 +257,7 @@
overflow-wrap: break-word; overflow-wrap: break-word;
} }
.stamp { .stamp {
transform: rotate(12deg); transform: rotate(12deg);
color: #555; color: #555;
font-size: 3rem; font-size: 3rem;

View File

@ -31,7 +31,7 @@
{{ ctrans('texts.type') }} {{ ctrans('texts.type') }}
</dt> </dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{{ $payment_method->meta?->brand }} {{ property_exists($payment_method->meta, 'brand') ? $payment_method->meta?->brand : ''}}
{{ property_exists($payment_method->meta, 'scheme') ? $payment_method->meta?->scheme : '' }} {{ property_exists($payment_method->meta, 'scheme') ? $payment_method->meta?->scheme : '' }}
</dd> </dd>
</div> </div>