From 1a813c365d7c7eb8c7bae9cc54fbbf608f4ac730 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 10:08:57 +1000 Subject: [PATCH 01/18] working on payfast --- app/Models/Gateway.php | 2 +- app/PaymentDrivers/PayFastPaymentDriver.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 209be095aff8..7b65f9fb93b1 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -85,7 +85,7 @@ class Gateway extends StaticModel return [GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => true]];//eWay break; case 11: - return [GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => false]];//Payfast + return [GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => true]];//Payfast break; case 7: return [ diff --git a/app/PaymentDrivers/PayFastPaymentDriver.php b/app/PaymentDrivers/PayFastPaymentDriver.php index e2e5816a85c1..15b420584976 100644 --- a/app/PaymentDrivers/PayFastPaymentDriver.php +++ b/app/PaymentDrivers/PayFastPaymentDriver.php @@ -28,7 +28,7 @@ class PayFastPaymentDriver extends BaseDriver public $refundable = false; //does this gateway support refunds? - public $token_billing = false; //does this gateway support token billing? + public $token_billing = true; //does this gateway support token billing? public $can_authorise_credit_card = true; //does this gateway support authorizations? From adf1214efbd0c0cd45a2ab0f7c5019be9a6cb51f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 10:26:21 +1000 Subject: [PATCH 02/18] Payfast --- app/PaymentDrivers/PayFast/Token.php | 57 +++++++++++++++++----------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/app/PaymentDrivers/PayFast/Token.php b/app/PaymentDrivers/PayFast/Token.php index 0a812f125924..2dcf554448d8 100644 --- a/app/PaymentDrivers/PayFast/Token.php +++ b/app/PaymentDrivers/PayFast/Token.php @@ -77,36 +77,47 @@ class Token $amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total; $amount = round(($amount * pow(10, $this->payfast->client->currency()->precision)),0); - // $header =[ - // 'merchant-id' => $this->payfast->company_gateway->getConfigField('merchantId'), - // 'timestamp' => now()->format('c'), - // 'version' => 'v1', - // ]; + $header =[ + 'merchant-id' => $this->payfast->company_gateway->getConfigField('merchantId'), + 'version' => 'v1', + 'timestamp' => now()->format('c'), + ]; - // $body = [ - // 'amount' => $amount, - // 'item_name' => 'purchase', - // 'item_description' => ctrans('texts.invoices') . ': ' . collect($payment_hash->invoices())->pluck('invoice_number'), - // // 'm_payment_id' => $payment_hash->hash, - // ]; + $body = [ + 'amount' => $amount, + 'item_name' => 'purchase', + 'item_description' => ctrans('texts.invoices') . ': ' . collect($payment_hash->invoices())->pluck('invoice_number'), + 'm_payment_id' => $payment_hash->hash, + ]; + + nlog(array_merge($header, $body)); // $header['signature'] = md5( $this->generate_parameter_string(array_merge($header, $body), false) ); - // $result = $this->send($header, $body, $cgt->token); - $api = new \PayFast\PayFastApi( - [ - 'merchantId' => $this->payfast->company_gateway->getConfigField('merchantId'), - 'passPhrase' => $this->payfast->company_gateway->getConfigField('passPhrase'), - 'testMode' => $this->payfast->company_gateway->getConfigField('testMode') - ] - ); + $header['signature'] = $this->genSig(array_merge($header, $body)); - $adhocArray = $api - ->subscriptions - ->adhoc($cgt->token, ['amount' => $amount, 'item_name' => 'purchase']); + nlog($header['signature']); + + $result = $this->send($header, $body, $cgt->token); + + nlog($result); + + // $api = new \PayFast\PayFastApi( + // [ + // 'merchantId' => $this->payfast->company_gateway->getConfigField('merchantId'), + // 'passPhrase' => $this->payfast->company_gateway->getConfigField('passPhrase'), + // 'testMode' => $this->payfast->company_gateway->getConfigField('testMode') + // ] + // ); + + // $adhocArray = $api + // ->subscriptions + // ->adhoc($cgt->token, ['amount' => $amount, 'item_name' => 'purchase']); + + + // nlog($adhocArray); - nlog($adhocArray); // /*Refactor and push to BaseDriver*/ // if ($data['response'] != null && $data['response']->getMessages()->getResultCode() == 'Ok') { From 9b65fba1c974adb18cc6c11d37706a99753e7c14 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 10:28:22 +1000 Subject: [PATCH 03/18] Payfast --- app/PaymentDrivers/PayFast/Token.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/PaymentDrivers/PayFast/Token.php b/app/PaymentDrivers/PayFast/Token.php index 2dcf554448d8..1b4a88d0f0ac 100644 --- a/app/PaymentDrivers/PayFast/Token.php +++ b/app/PaymentDrivers/PayFast/Token.php @@ -101,7 +101,7 @@ class Token $result = $this->send($header, $body, $cgt->token); nlog($result); - + // $api = new \PayFast\PayFastApi( // [ // 'merchantId' => $this->payfast->company_gateway->getConfigField('merchantId'), @@ -210,6 +210,8 @@ class Token } } + nlog(http_build_query($fields)); + return md5(http_build_query($fields)); } From ad4413018f1bc1b75ee62e4006d8c170755f7430 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 10:29:26 +1000 Subject: [PATCH 04/18] Payfast --- app/PaymentDrivers/PayFast/Token.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/PaymentDrivers/PayFast/Token.php b/app/PaymentDrivers/PayFast/Token.php index 1b4a88d0f0ac..e63b0fa50a33 100644 --- a/app/PaymentDrivers/PayFast/Token.php +++ b/app/PaymentDrivers/PayFast/Token.php @@ -90,11 +90,11 @@ class Token 'm_payment_id' => $payment_hash->hash, ]; - nlog(array_merge($header, $body)); + nlog(array_merge($body, $header)); // $header['signature'] = md5( $this->generate_parameter_string(array_merge($header, $body), false) ); - $header['signature'] = $this->genSig(array_merge($header, $body)); + $header['signature'] = $this->genSig(array_merge($body, $header)); nlog($header['signature']); @@ -211,7 +211,7 @@ class Token } nlog(http_build_query($fields)); - + return md5(http_build_query($fields)); } From fbe4ac3fb6e87eea7c0af2a9bf848b9f82b975fc Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 10:34:02 +1000 Subject: [PATCH 05/18] Payfast --- app/PaymentDrivers/PayFast/Token.php | 2 +- app/PaymentDrivers/PayFastPaymentDriver.php | 31 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/app/PaymentDrivers/PayFast/Token.php b/app/PaymentDrivers/PayFast/Token.php index e63b0fa50a33..dcfcd92d04ee 100644 --- a/app/PaymentDrivers/PayFast/Token.php +++ b/app/PaymentDrivers/PayFast/Token.php @@ -94,7 +94,7 @@ class Token // $header['signature'] = md5( $this->generate_parameter_string(array_merge($header, $body), false) ); - $header['signature'] = $this->genSig(array_merge($body, $header)); + $header['signature'] = $this->payfast->generateTokenSignature(array_merge($body, $header)); nlog($header['signature']); diff --git a/app/PaymentDrivers/PayFastPaymentDriver.php b/app/PaymentDrivers/PayFastPaymentDriver.php index 15b420584976..aa563c744546 100644 --- a/app/PaymentDrivers/PayFastPaymentDriver.php +++ b/app/PaymentDrivers/PayFastPaymentDriver.php @@ -123,7 +123,36 @@ class PayFastPaymentDriver extends BaseDriver return (new Token($this))->tokenBilling($cgt, $payment_hash); } - public function generateSignature($data) + public function generateTokenSignature($data) + { + $fields = []; + + $keys = [ + 'merchant-id', + 'version', + 'timestamp', + 'amount', + 'item_name', + 'item_description', + 'itn', + 'm_payment_id', + 'cc_css', + 'split_payment' + ]; + + foreach($keys as $key) + { + if (!empty($data[$key])) { + $fields[$key] = $data[$key]; + } + } + + nlog(http_build_query($fields)); + + return md5(http_build_query($fields)); + } + + public function generateSignature($data) { $fields = array(); From 6a51bc258c65d0cd3f24b5295b991f7dc89cdb74 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 10:46:54 +1000 Subject: [PATCH 06/18] Payfast --- app/PaymentDrivers/PayFastPaymentDriver.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/PaymentDrivers/PayFastPaymentDriver.php b/app/PaymentDrivers/PayFastPaymentDriver.php index aa563c744546..6ffedfe25b0a 100644 --- a/app/PaymentDrivers/PayFastPaymentDriver.php +++ b/app/PaymentDrivers/PayFastPaymentDriver.php @@ -147,6 +147,9 @@ class PayFastPaymentDriver extends BaseDriver } } + if($this->company_gateway->getConfigField('passPhrase')) + $fields['passphrase'] = $this->company_gateway->getConfigField('passPhrase'); + nlog(http_build_query($fields)); return md5(http_build_query($fields)); From 45b4267916ac915138eb2794e98d5b9599743657 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 10:52:09 +1000 Subject: [PATCH 07/18] Payfast --- app/PaymentDrivers/PayFast/Token.php | 6 +++--- app/PaymentDrivers/PayFastPaymentDriver.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/PaymentDrivers/PayFast/Token.php b/app/PaymentDrivers/PayFast/Token.php index dcfcd92d04ee..43208c58dd36 100644 --- a/app/PaymentDrivers/PayFast/Token.php +++ b/app/PaymentDrivers/PayFast/Token.php @@ -162,8 +162,8 @@ class Token protected function generate_parameter_string( $api_data, $sort_data_before_merge = true, $skip_empty_values = true ) { // if sorting is required the passphrase should be added in before sort. - if ( ! empty( $this->payfast->company_gateway->getConfigField('passPhrase') ) && $sort_data_before_merge ) - $api_data['passphrase'] = $this->payfast->company_gateway->getConfigField('passPhrase'); + if ( ! empty( $this->payfast->company_gateway->getConfigField('passphrase') ) && $sort_data_before_merge ) + $api_data['passphrase'] = $this->payfast->company_gateway->getConfigField('passphrase'); if ( $sort_data_before_merge ) { ksort( $api_data ); @@ -186,7 +186,7 @@ class Token if ( $sort_data_before_merge ) { $parameter_string = rtrim( $parameter_string, '&' ); } elseif ( ! empty( $this->pass_phrase ) ) { - $parameter_string .= 'passphrase=' . urlencode( $this->payfast->company_gateway->getConfigField('passPhrase') ); + $parameter_string .= 'passphrase=' . urlencode( $this->payfast->company_gateway->getConfigField('passphrase') ); } else { $parameter_string = rtrim( $parameter_string, '&' ); } diff --git a/app/PaymentDrivers/PayFastPaymentDriver.php b/app/PaymentDrivers/PayFastPaymentDriver.php index 6ffedfe25b0a..591c6d347741 100644 --- a/app/PaymentDrivers/PayFastPaymentDriver.php +++ b/app/PaymentDrivers/PayFastPaymentDriver.php @@ -72,7 +72,7 @@ class PayFastPaymentDriver extends BaseDriver [ 'merchantId' => $this->company_gateway->getConfigField('merchantId'), 'merchantKey' => $this->company_gateway->getConfigField('merchantKey'), - 'passPhrase' => $this->company_gateway->getConfigField('passPhrase'), + 'passPhrase' => $this->company_gateway->getConfigField('passphrase'), 'testMode' => $this->company_gateway->getConfigField('testMode') ] ); @@ -147,8 +147,8 @@ class PayFastPaymentDriver extends BaseDriver } } - if($this->company_gateway->getConfigField('passPhrase')) - $fields['passphrase'] = $this->company_gateway->getConfigField('passPhrase'); + if($this->company_gateway->getConfigField('passphrase')) + $fields['passphrase'] = $this->company_gateway->getConfigField('passphrase'); nlog(http_build_query($fields)); From 0d44493e9c0a17abd0bc84b4fc6038ffd2974f01 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 11:08:31 +1000 Subject: [PATCH 08/18] Return null for backups if none exist --- app/Transformers/InvoiceHistoryTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Transformers/InvoiceHistoryTransformer.php b/app/Transformers/InvoiceHistoryTransformer.php index fa8341e7972b..f8b31f415656 100644 --- a/app/Transformers/InvoiceHistoryTransformer.php +++ b/app/Transformers/InvoiceHistoryTransformer.php @@ -30,7 +30,7 @@ class InvoiceHistoryTransformer extends EntityTransformer public function transform(?Backup $backup) { if(!$backup) - return []; + return null; return [ 'id' => $this->encodePrimaryKey($backup->id), From ff6767b5e40405db2576c99afdb720fa97aa1037 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 11:17:04 +1000 Subject: [PATCH 09/18] Catch bounces --- app/Http/Controllers/PostMarkController.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/PostMarkController.php b/app/Http/Controllers/PostMarkController.php index ceb9e1e4e0e9..a6b000d66feb 100644 --- a/app/Http/Controllers/PostMarkController.php +++ b/app/Http/Controllers/PostMarkController.php @@ -12,6 +12,7 @@ namespace App\Http\Controllers; use App\DataMapper\Analytics\EmailBounce; +use App\DataMapper\Analytics\Mail\EmailBounce; use App\DataMapper\Analytics\Mail\EmailSpam; use App\Jobs\Util\SystemLogger; use App\Libraries\MultiDB; @@ -74,7 +75,6 @@ class PostMarkController extends BaseController if($request->header('X-API-SECURITY') && $request->header('X-API-SECURITY') == config('postmark.secret')) { - // nlog($request->all()); MultiDB::findAndSetDbByCompanyKey($request->input('Tag')); @@ -165,13 +165,13 @@ class PostMarkController extends BaseController $this->invitation->email_status = 'bounced'; $this->invitation->save(); - // $bounce = new EmailBounce( - // $request->input('Tag'), - // $request->input('From'), - // $request->input('MessageID') - // ); + $bounce = new EmailBounce( + $request->input('Tag'), + $request->input('From'), + $request->input('MessageID') + ); - // LightLogs::create($bounce)->batch(); + LightLogs::create($bounce)->batch(); SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company); } From e63d9828f14fbaa4a6656042c1ce07b1f4004215 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 21:06:42 +1000 Subject: [PATCH 10/18] Implement future migration refactor for v4 when we upgrade to L6 --- app/Http/Controllers/MigrationController.php | 50 +++++++++++++++----- app/Models/Company.php | 2 +- app/Utils/Traits/Inviteable.php | 4 +- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/app/Http/Controllers/MigrationController.php b/app/Http/Controllers/MigrationController.php index dad349fde609..d7f1d1ae3463 100644 --- a/app/Http/Controllers/MigrationController.php +++ b/app/Http/Controllers/MigrationController.php @@ -24,6 +24,7 @@ use App\Models\CompanyToken; use App\Utils\Ninja; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Http\Request; +use Illuminate\Http\UploadedFile; use Illuminate\Support\Str; use Illuminate\Support\Facades\App; @@ -231,10 +232,23 @@ class MigrationController extends BaseController * @return \Illuminate\Http\JsonResponse|void */ public function startMigration(Request $request) - { - nlog("Starting Migration"); + { - $companies = json_decode($request->companies); + // v4 Laravel 6 + + // $companies = []; + + // foreach($request->all() as $input){ + + // if($input instanceof UploadedFile) + // nlog('is file'); + // else + // $companies[] = json_decode($input); + // } + + nlog("Starting Migration"); + + $companies = json_decode($request->companies,1); if (app()->environment() === 'local') { nlog($request->all()); @@ -250,19 +264,31 @@ class MigrationController extends BaseController } finally { // Controller logic here - foreach ($companies as $company) { - $is_valid = $request->file($company->company_index)->isValid(); + foreach($companies as $company) + { - if (!$is_valid) { - continue; - } + $company = (array)$company; + + // v4 Laravel 6 + // $input = $request->all(); + + // foreach ($input as $company) { + + // if($company instanceof UploadedFile) + // continue; + // else + // $company = json_decode($company,1); + + // if (!$company || !is_int($company['company_index'] || !$request->file($company['company_index'])->isValid())) { + // continue; + // } $user = auth()->user(); $company_count = $user->account->companies()->count(); // Look for possible existing company (based on company keys). - $existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company->company_key])->first(); + $existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first(); App::forgetInstance('translator'); $t = app('translator'); @@ -291,7 +317,7 @@ class MigrationController extends BaseController $checks = [ 'existing_company' => $existing_company ? (bool)1 : false, - 'force' => property_exists($company, 'force') ? (bool) $company->force : false, + 'force' => array_key_exists('force', $company) ? (bool) $company['force'] : false, ]; // If there's existing company and ** no ** force is provided - skip migration. @@ -378,10 +404,10 @@ class MigrationController extends BaseController ]); } - $migration_file = $request->file($company->company_index) + $migration_file = $request->file($company['company_index']) ->storeAs( 'migrations', - $request->file($company->company_index)->getClientOriginalName(), + $request->file($company['company_index'])->getClientOriginalName(), 'public' ); diff --git a/app/Models/Company.php b/app/Models/Company.php index 58a90c2b3367..d131e401b044 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -485,7 +485,7 @@ class Company extends BaseModel { if (Ninja::isHosted()) { - if($this->portal_mode == 'domain') + if($this->portal_mode == 'domain' && strlen($this->portal_domain) > 3) return $this->portal_domain; return "https://{$this->subdomain}." . config('ninja.app_domain'); diff --git a/app/Utils/Traits/Inviteable.php b/app/Utils/Traits/Inviteable.php index 91520a63804d..519b858d95c0 100644 --- a/app/Utils/Traits/Inviteable.php +++ b/app/Utils/Traits/Inviteable.php @@ -48,7 +48,7 @@ trait Inviteable $entity_type = Str::snake(class_basename($this->entityType())); if(Ninja::isHosted()){ - $domain = isset($this->company->portal_domain) ? $this->company->portal_domain : $this->company->domain(); + $domain = $this->company->domain(); } else $domain = config('ninja.app_url'); @@ -75,7 +75,7 @@ trait Inviteable { if(Ninja::isHosted()) - $domain = isset($this->company->portal_domain) ? $this->company->portal_domain : $this->company->domain(); + $domain = $this->company->domain(); else $domain = config('ninja.app_url'); From 199a0aed5598e972329f5539006b62f4cdd34e11 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 21:11:01 +1000 Subject: [PATCH 11/18] Minor fixes for company importer --- app/Jobs/Company/CompanyImport.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Jobs/Company/CompanyImport.php b/app/Jobs/Company/CompanyImport.php index fc7aa0b4aece..2898617112cc 100644 --- a/app/Jobs/Company/CompanyImport.php +++ b/app/Jobs/Company/CompanyImport.php @@ -794,6 +794,7 @@ class CompanyImport implements ShouldQueue ['clients' => 'client_id'], ['projects' => 'project_id'], ['vendors' => 'vendor_id'], + ['invoices' => 'invoice_id'], ], 'expenses', 'number'); From e2502737870281451fafa055aa658e49aa853892 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 21:42:25 +1000 Subject: [PATCH 12/18] Fixes for displaying defaults on preview --- app/Http/Controllers/PreviewController.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/PreviewController.php b/app/Http/Controllers/PreviewController.php index 51ddfb9da2ff..8ae3eb21e6ae 100644 --- a/app/Http/Controllers/PreviewController.php +++ b/app/Http/Controllers/PreviewController.php @@ -212,7 +212,10 @@ class PreviewController extends BaseController } $entity_obj = $repo->save($request->all(), $entity_obj); - $entity_obj->service()->fillDefaults()->save(); + + if(!$request->has('entity_id')) + $entity_obj->service()->fillDefaults()->save(); + $entity_obj->load('client'); App::forgetInstance('translator'); From 34a90d2ba8ca046b3547f76dbda27155b81ee86d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 29 Sep 2021 21:48:22 +1000 Subject: [PATCH 13/18] Map Client Registration fields --- app/DataMapper/ClientRegistrationFields.php | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 app/DataMapper/ClientRegistrationFields.php diff --git a/app/DataMapper/ClientRegistrationFields.php b/app/DataMapper/ClientRegistrationFields.php new file mode 100644 index 000000000000..242cd7ac0a27 --- /dev/null +++ b/app/DataMapper/ClientRegistrationFields.php @@ -0,0 +1,30 @@ + 'name', + 'value' => 'name', + 'required' => true + ], + + + ]; + } +} From 43822fbfddc7c0ba008b250ac4adbe5b0af53daf Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 30 Sep 2021 04:58:48 +1000 Subject: [PATCH 14/18] Return blank Backup object if none exists --- app/Repositories/ClientContactRepository.php | 4 ++-- app/Transformers/InvoiceHistoryTransformer.php | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/Repositories/ClientContactRepository.php b/app/Repositories/ClientContactRepository.php index eedab840d3de..2bc644f8ba4d 100644 --- a/app/Repositories/ClientContactRepository.php +++ b/app/Repositories/ClientContactRepository.php @@ -80,10 +80,10 @@ class ClientContactRepository extends BaseRepository }); //need to reload here to shake off stale contacts - $client->load('contacts'); + $client->fresh(); //always made sure we have one blank contact to maintain state - if ($client->contacts->count() == 0) { + if ($client->contacts()->count() == 0) { $new_contact = ClientContactFactory::create($client->company_id, $client->user_id); $new_contact->client_id = $client->id; $new_contact->contact_key = Str::random(40); diff --git a/app/Transformers/InvoiceHistoryTransformer.php b/app/Transformers/InvoiceHistoryTransformer.php index f8b31f415656..6b9ad6af8427 100644 --- a/app/Transformers/InvoiceHistoryTransformer.php +++ b/app/Transformers/InvoiceHistoryTransformer.php @@ -29,8 +29,19 @@ class InvoiceHistoryTransformer extends EntityTransformer public function transform(?Backup $backup) { - if(!$backup) - return null; + if(!$backup){ + + return [ + 'id' => '', + 'activity_id' => '', + 'json_backup' => (string) '', + 'html_backup' => (string) '', + 'amount' => (float) 0, + 'created_at' => (int) 0, + 'updated_at' => (int) 0, + ]; + + } return [ 'id' => $this->encodePrimaryKey($backup->id), From a7a76e806cd1b052a809aab6af7dc0e4b16b2dda Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 30 Sep 2021 08:13:48 +1000 Subject: [PATCH 15/18] Minor fixes --- app/Http/Controllers/BaseController.php | 2 ++ .../Support/Messages/SendingController.php | 2 +- app/Mail/SupportMessageSent.php | 16 +++++++++------- app/Transformers/RecurringExpenseTransformer.php | 1 + app/Transformers/RecurringInvoiceTransformer.php | 2 +- app/Utils/HtmlEngine.php | 2 ++ resources/views/index/index.blade.php | 2 +- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 2da7852bed65..d5df45487874 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -746,6 +746,8 @@ class BaseController extends Controller //pass referral code to front end $data['rc'] = request()->has('rc') ? request()->input('rc') : ''; $data['build'] = request()->has('build') ? request()->input('build') : ''; + $data['login'] = request()->has('login') ? request()->input('login') : "false"; + $data['user_agent'] = request()->server('HTTP_USER_AGENT'); $data['path'] = $this->setBuild(); diff --git a/app/Http/Controllers/Support/Messages/SendingController.php b/app/Http/Controllers/Support/Messages/SendingController.php index 62baf5eacde4..38082d581e56 100644 --- a/app/Http/Controllers/Support/Messages/SendingController.php +++ b/app/Http/Controllers/Support/Messages/SendingController.php @@ -76,7 +76,7 @@ class SendingController extends Controller } Mail::to(config('ninja.contact.ninja_official_contact')) - ->send(new SupportMessageSent($request->input('message'), $send_logs)); + ->send(new SupportMessageSent($request->all(), $send_logs)); return response()->json([ 'success' => true, diff --git a/app/Mail/SupportMessageSent.php b/app/Mail/SupportMessageSent.php index ec371fc919e1..b326ba45086d 100644 --- a/app/Mail/SupportMessageSent.php +++ b/app/Mail/SupportMessageSent.php @@ -13,13 +13,13 @@ class SupportMessageSent extends Mailable { // use Queueable, SerializesModels; - public $support_message; + public $data; public $send_logs; - public function __construct($support_message, $send_logs) + public function __construct(array $data, $send_logs) { - $this->support_message = $support_message; + $this->data = $data; $this->send_logs = $send_logs; } @@ -63,17 +63,19 @@ class SupportMessageSent extends Mailable $user = auth()->user(); $db = str_replace("db-ninja-", "", $company->db); $is_large = $company->is_large ? "L" : "S"; - + $platform = array_key_exists('platform', $this->data) ? $this->data['platform'] : "U"; + $migrated = strlen($company->company_key) == 32 ? "M" : ""; + if(Ninja::isHosted()) - $subject = "{$priority}Hosted-{$db}-{$is_large} :: {$plan} :: ".date('M jS, g:ia'); + $subject = "{$priority}Hosted-{$db}-{$is_large}{$platform}{$migrated} :: {$plan} :: ".date('M jS, g:ia'); else - $subject = "{$priority}Self Hosted :: {$plan} :: ".date('M jS, g:ia'); + $subject = "{$priority}Self Hosted :: {$plan}{$platform} :: ".date('M jS, g:ia'); return $this->from(config('mail.from.address'), $user->present()->name()) ->replyTo($user->email, $user->present()->name()) ->subject($subject) ->view('email.support.message', [ - 'support_message' => $this->support_message, + 'support_message' => $this->data['support_message'], 'system_info' => $system_info, 'laravel_log' => $log_lines, 'logo' => $company->present()->logo(), diff --git a/app/Transformers/RecurringExpenseTransformer.php b/app/Transformers/RecurringExpenseTransformer.php index 6332e4535aa1..c7b59a795e7c 100644 --- a/app/Transformers/RecurringExpenseTransformer.php +++ b/app/Transformers/RecurringExpenseTransformer.php @@ -101,6 +101,7 @@ class RecurringExpenseTransformer extends EntityTransformer 'remaining_cycles' => (int) $recurring_expense->remaining_cycles, 'last_sent_date' => $recurring_expense->last_sent_date ?: '', 'next_send_date' => $recurring_expense->next_send_date ?: '', + 'recurring_dates' => (array) [], ]; if(request()->has('show_dates') && request()->query('show_dates') == 'true') diff --git a/app/Transformers/RecurringInvoiceTransformer.php b/app/Transformers/RecurringInvoiceTransformer.php index a845e447c105..ce55314599cf 100644 --- a/app/Transformers/RecurringInvoiceTransformer.php +++ b/app/Transformers/RecurringInvoiceTransformer.php @@ -127,7 +127,7 @@ class RecurringInvoiceTransformer extends EntityTransformer 'due_date_days' => (string) $invoice->due_date_days ?: '', 'paid_to_date' => (float) $invoice->paid_to_date, 'subscription_id' => (string)$this->encodePrimaryKey($invoice->subscription_id), - + 'recurring_dates' => (array) [], ]; diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index 808c7b5a3e9e..713dacd71cbb 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -158,6 +158,7 @@ class HtmlEngine $data['$view_link'] = ['value' => ''.ctrans('texts.view_quote').'', 'label' => ctrans('texts.view_quote')]; $data['$viewLink'] = &$data['$view_link']; $data['$viewButton'] = &$data['$view_link']; + $data['$view_button'] = &$data['$view_link']; $data['$approveButton'] = ['value' => ''.ctrans('texts.view_quote').'', 'label' => ctrans('texts.approve')]; $data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_quote')]; $data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->entity->client->date_format(), $this->entity->client->locale()) ?: ' ', 'label' => ctrans('texts.quote_date')]; @@ -171,6 +172,7 @@ class HtmlEngine $data['$terms'] = &$data['$entity.terms']; $data['$view_link'] = ['value' => ''.ctrans('texts.view_credit').'', 'label' => ctrans('texts.view_credit')]; $data['$viewButton'] = &$data['$view_link']; + $data['$view_button'] = &$data['$view_link']; $data['$viewLink'] = &$data['$view_link']; $data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_credit')]; // $data['$view_link'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_credit')]; diff --git a/resources/views/index/index.blade.php b/resources/views/index/index.blade.php index bf4de0c63056..2ec7fc0ff4e3 100644 --- a/resources/views/index/index.blade.php +++ b/resources/views/index/index.blade.php @@ -1,5 +1,5 @@ - + From 4fdd709e99fbe4b2ea340c74b6c0b509036e5e1c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 30 Sep 2021 08:14:48 +1000 Subject: [PATCH 16/18] Default client registration fields --- app/DataMapper/ClientRegistrationFields.php | 81 +++++++++++++++++-- app/Factory/CompanyFactory.php | 4 +- .../Requests/Company/UpdateCompanyRequest.php | 1 + app/Jobs/Company/CreateCompany.php | 4 +- app/Models/Company.php | 2 + .../InvoiceHistoryTransformer.php | 8 +- ...dd_required_client_registration_fields.php | 30 +++++++ 7 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 database/migrations/2021_09_29_190258_add_required_client_registration_fields.php diff --git a/app/DataMapper/ClientRegistrationFields.php b/app/DataMapper/ClientRegistrationFields.php index 242cd7ac0a27..f56252f6fd70 100644 --- a/app/DataMapper/ClientRegistrationFields.php +++ b/app/DataMapper/ClientRegistrationFields.php @@ -19,12 +19,83 @@ class ClientRegistrationFields $data = [ [ - 'key' => 'name', - 'value' => 'name', + 'key' => 'first_name', 'required' => true ], - - + [ + 'key' => 'last_name', + 'required' => true + ], + [ + 'key' => 'email', + 'required' => true + ], + [ + 'key' => 'phone', + 'required' => true + ], + [ + 'key' => 'password', + 'required' => true + ], + [ + 'key' => 'name', + 'required' => false + ], + [ + 'key' => 'website', + 'required' => false + ], + [ + 'key' => 'address1', + 'required' => false + ], + [ + 'key' => 'address2', + 'required' => false + ], + [ + 'key' => 'city', + 'required' => false + ], + [ + 'key' => 'state', + 'required' => false + ], + [ + 'key' => 'postal_code', + 'required' => false + ], + [ + 'key' => 'country_id', + 'required' => false + ], + [ + 'key' => 'custom_value1', + 'required' => false + ], + [ + 'key' => 'custom_value2', + 'required' => false + ], + [ + 'key' => 'custom_value3', + 'required' => false + ], + [ + 'key' => 'custom_value4', + 'required' => false + ], + [ + 'key' => 'public_notes', + 'required' => false + ], + [ + 'key' => 'vat_number', + 'required' => false + ], ]; + + return $data; } -} +} \ No newline at end of file diff --git a/app/Factory/CompanyFactory.php b/app/Factory/CompanyFactory.php index 7043bbdba023..4f62bca9fdc4 100644 --- a/app/Factory/CompanyFactory.php +++ b/app/Factory/CompanyFactory.php @@ -11,6 +11,7 @@ namespace App\Factory; +use App\DataMapper\ClientRegistrationFields; use App\DataMapper\CompanySettings; use App\Libraries\MultiDB; use App\Models\Company; @@ -35,7 +36,8 @@ class CompanyFactory $company->db = config('database.default'); //$company->custom_fields = (object) ['invoice1' => '1', 'invoice2' => '2', 'client1'=>'3']; $company->custom_fields = (object) []; - + $company->client_registration_fields = ClientRegistrationFields::generate(); + if(Ninja::isHosted()) $company->subdomain = MultiDB::randomSubdomainGenerator(); else diff --git a/app/Http/Requests/Company/UpdateCompanyRequest.php b/app/Http/Requests/Company/UpdateCompanyRequest.php index 609876cbe5ee..d89561baeef6 100644 --- a/app/Http/Requests/Company/UpdateCompanyRequest.php +++ b/app/Http/Requests/Company/UpdateCompanyRequest.php @@ -44,6 +44,7 @@ class UpdateCompanyRequest extends Request $rules['size_id'] = 'integer|nullable'; $rules['country_id'] = 'integer|nullable'; $rules['work_email'] = 'email|nullable'; + // $rules['client_registration_fields'] = 'array'; if (isset($input['portal_mode']) && ($input['portal_mode'] == 'domain' || $input['portal_mode'] == 'iframe')) { $rules['portal_domain'] = 'sometimes|url'; diff --git a/app/Jobs/Company/CreateCompany.php b/app/Jobs/Company/CreateCompany.php index ca3624ec443d..cbb6a1afe157 100644 --- a/app/Jobs/Company/CreateCompany.php +++ b/app/Jobs/Company/CreateCompany.php @@ -11,6 +11,7 @@ namespace App\Jobs\Company; +use App\DataMapper\ClientRegistrationFields; use App\DataMapper\CompanySettings; use App\Libraries\MultiDB; use App\Models\Company; @@ -62,7 +63,8 @@ class CreateCompany $company->subdomain = isset($this->request['subdomain']) ? $this->request['subdomain'] : ''; $company->custom_fields = new \stdClass; $company->default_password_timeout = 1800000; - + $company->client_registration_fields = ClientRegistrationFields::generate(); + if(Ninja::isHosted()) $company->subdomain = MultiDB::randomSubdomainGenerator(); else diff --git a/app/Models/Company.php b/app/Models/Company.php index d131e401b044..86554fe5001e 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -96,6 +96,7 @@ class Company extends BaseModel 'show_task_end_date', 'use_comma_as_decimal_place', 'report_include_drafts', + 'client_registration_fields', ]; protected $hidden = [ @@ -111,6 +112,7 @@ class Company extends BaseModel 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', + 'client_registration_fields' => 'array', ]; protected $with = [ diff --git a/app/Transformers/InvoiceHistoryTransformer.php b/app/Transformers/InvoiceHistoryTransformer.php index 6b9ad6af8427..fd2547af0966 100644 --- a/app/Transformers/InvoiceHistoryTransformer.php +++ b/app/Transformers/InvoiceHistoryTransformer.php @@ -34,8 +34,8 @@ class InvoiceHistoryTransformer extends EntityTransformer return [ 'id' => '', 'activity_id' => '', - 'json_backup' => (string) '', - 'html_backup' => (string) '', + // 'json_backup' => (string) '', + // 'html_backup' => (string) '', 'amount' => (float) 0, 'created_at' => (int) 0, 'updated_at' => (int) 0, @@ -46,8 +46,8 @@ class InvoiceHistoryTransformer extends EntityTransformer return [ 'id' => $this->encodePrimaryKey($backup->id), 'activity_id' => $this->encodePrimaryKey($backup->activity_id), - 'json_backup' => (string) $backup->json_backup ?: '', - 'html_backup' => (string) $backup->html_backup ?: '', + // 'json_backup' => (string) $backup->json_backup ?: '', + // 'html_backup' => (string) $backup->html_backup ?: '', 'amount' => (float) $backup->amount, 'created_at' => (int) $backup->created_at, 'updated_at' => (int) $backup->updated_at, diff --git a/database/migrations/2021_09_29_190258_add_required_client_registration_fields.php b/database/migrations/2021_09_29_190258_add_required_client_registration_fields.php new file mode 100644 index 000000000000..436f503b0142 --- /dev/null +++ b/database/migrations/2021_09_29_190258_add_required_client_registration_fields.php @@ -0,0 +1,30 @@ +mediumText('client_registration_fields')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} From c718c6d19b38933798d671c03a565859842d4b20 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 30 Sep 2021 11:42:27 +1000 Subject: [PATCH 17/18] Add Address to braintree create customer --- app/Jobs/RecurringInvoice/SendRecurring.php | 1 - app/PaymentDrivers/BraintreePaymentDriver.php | 9 +++++ ...dd_required_client_registration_fields.php | 36 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index 7945c4217185..9ee37c268b14 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -132,7 +132,6 @@ class SendRecurring implements ShouldQueue }); if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) { - nlog("attempting to autobill {$invoice->number}"); $invoice->service()->autoBill()->save(); diff --git a/app/PaymentDrivers/BraintreePaymentDriver.php b/app/PaymentDrivers/BraintreePaymentDriver.php index f1d0858284cf..2c5cc40a507b 100644 --- a/app/PaymentDrivers/BraintreePaymentDriver.php +++ b/app/PaymentDrivers/BraintreePaymentDriver.php @@ -119,6 +119,15 @@ class BraintreePaymentDriver extends BaseDriver ]); if ($result->success) { + + $address = $this->gateway->address()->create([ + 'customerId' => $result->customer->id, + 'firstName' => $this->client->present()->name, + 'streetAddress' => $this->client->address1, + 'postalCode' => $this->client->postal_code, + 'countryCodeAlpha2' => $this->client->country ? $this->client->country->iso_3166_2 : '', + ]); + return $result->customer; } } diff --git a/database/migrations/2021_09_29_190258_add_required_client_registration_fields.php b/database/migrations/2021_09_29_190258_add_required_client_registration_fields.php index 436f503b0142..4ae9eba8400a 100644 --- a/database/migrations/2021_09_29_190258_add_required_client_registration_fields.php +++ b/database/migrations/2021_09_29_190258_add_required_client_registration_fields.php @@ -1,5 +1,9 @@ mediumText('client_registration_fields')->nullable(); }); + + Company::all()->each(function ($company){ + $company->update(['client_registration_fields' => ClientRegistrationFields::generate()]); + }); + + + Model::unguard(); + + + $currencies = [ +['id' => 111, 'name' => 'Cuban Peso','code' => 'CUP', 'symbol' => '₱', 'precision' => '2','thousand_separator' => ',','decimal_separator' => '.'], + + ]; + + foreach ($currencies as $currency) { + $record = Currency::whereCode($currency['code'])->first(); + if ($record) { + $record->name = $currency['name']; + $record->symbol = $currency['symbol']; + $record->precision = $currency['precision']; + $record->thousand_separator = $currency['thousand_separator']; + $record->decimal_separator = $currency['decimal_separator']; + if (isset($currency['swap_currency_symbol'])) { + $record->swap_currency_symbol = $currency['swap_currency_symbol']; + } + $record->save(); + } else { + Currency::create($currency); + } + } + } /** From 84d807f12e6f1dadc1758744ac021ad951f13b87 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 30 Sep 2021 13:09:04 +1000 Subject: [PATCH 18/18] return blank strings for html_backup --- app/Transformers/InvoiceHistoryTransformer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Transformers/InvoiceHistoryTransformer.php b/app/Transformers/InvoiceHistoryTransformer.php index fd2547af0966..e647bf5116c7 100644 --- a/app/Transformers/InvoiceHistoryTransformer.php +++ b/app/Transformers/InvoiceHistoryTransformer.php @@ -34,8 +34,8 @@ class InvoiceHistoryTransformer extends EntityTransformer return [ 'id' => '', 'activity_id' => '', - // 'json_backup' => (string) '', - // 'html_backup' => (string) '', + 'json_backup' => (string) '', + 'html_backup' => (string) '', 'amount' => (float) 0, 'created_at' => (int) 0, 'updated_at' => (int) 0, @@ -46,8 +46,8 @@ class InvoiceHistoryTransformer extends EntityTransformer return [ 'id' => $this->encodePrimaryKey($backup->id), 'activity_id' => $this->encodePrimaryKey($backup->activity_id), - // 'json_backup' => (string) $backup->json_backup ?: '', - // 'html_backup' => (string) $backup->html_backup ?: '', + 'json_backup' => (string) '', + 'html_backup' => (string) '', 'amount' => (float) $backup->amount, 'created_at' => (int) $backup->created_at, 'updated_at' => (int) $backup->updated_at,