diff --git a/app/Factory/CloneQuoteToInvoiceFactory.php b/app/Factory/CloneQuoteToInvoiceFactory.php index 086b6db742c5..b04b8104253d 100644 --- a/app/Factory/CloneQuoteToInvoiceFactory.php +++ b/app/Factory/CloneQuoteToInvoiceFactory.php @@ -29,7 +29,7 @@ class CloneQuoteToInvoiceFactory unset($quote_array['id']); unset($quote_array['invitations']); unset($quote_array['terms']); - unset($quote_array['public_notes']); + // unset($quote_array['public_notes']); unset($quote_array['footer']); unset($quote_array['design_id']); diff --git a/app/Http/Controllers/SubdomainController.php b/app/Http/Controllers/SubdomainController.php index 20334c32c111..6a25f795608d 100644 --- a/app/Http/Controllers/SubdomainController.php +++ b/app/Http/Controllers/SubdomainController.php @@ -29,6 +29,7 @@ class SubdomainController extends BaseController 'preview', 'invoiceninja', 'cname', + 'sandbox', ]; public function __construct() diff --git a/app/Jobs/Import/CSVImport.php b/app/Jobs/Import/CSVImport.php index dd6d22392cc6..b5896b53203b 100644 --- a/app/Jobs/Import/CSVImport.php +++ b/app/Jobs/Import/CSVImport.php @@ -38,6 +38,7 @@ use App\Repositories\BaseRepository; use App\Repositories\ClientRepository; use App\Repositories\InvoiceRepository; use App\Repositories\PaymentRepository; +use App\Utils\Ninja; use App\Utils\Traits\CleanLineItems; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -52,6 +53,7 @@ use League\Csv\Reader; use League\Csv\Statement; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; +use Illuminate\Support\Facades\App; class CSVImport implements ShouldQueue { @@ -132,6 +134,10 @@ class CSVImport implements ShouldQueue { 'company' => $this->company, ]; + App::forgetInstance('translator'); + $t = app('translator'); + $t->replace(Ninja::transformTranslations($this->company->settings)); + $nmo = new NinjaMailerObject; $nmo->mailable = new ImportCompleted($this->company, $data); $nmo->company = $this->company; diff --git a/app/Observers/PaymentObserver.php b/app/Observers/PaymentObserver.php index bacff53c5a89..976d261c3e1c 100644 --- a/app/Observers/PaymentObserver.php +++ b/app/Observers/PaymentObserver.php @@ -29,6 +29,9 @@ class PaymentObserver ->where('event_id', Webhook::EVENT_CREATE_PAYMENT) ->exists(); + if($payment->invoices()->exists()) + $payment->load('invoices'); + if ($subscriptions) { WebhookHandler::dispatch(Webhook::EVENT_CREATE_PAYMENT, $payment, $payment->company); } diff --git a/app/PaymentDrivers/PayFast/Token.php b/app/PaymentDrivers/PayFast/Token.php index fc1235a0d3cc..0a812f125924 100644 --- a/app/PaymentDrivers/PayFast/Token.php +++ b/app/PaymentDrivers/PayFast/Token.php @@ -77,31 +77,36 @@ 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'), + // 'timestamp' => now()->format('c'), + // 'version' => 'v1', + // ]; - nlog($header); + // $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, - 'passphrase' => $this->payfast->company_gateway->getConfigField('passphrase'), - ]; - - $header['signature'] = $this->genSig(array_merge($header, $body)); - - nlog($header['signature']); - nlog($header['timestamp']); - nlog($this->payfast->company_gateway->getConfigField('merchantId')); + // $header['signature'] = md5( $this->generate_parameter_string(array_merge($header, $body), false) ); - $result = $this->send($header, $body, $cgt->token); + // $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') + ] + ); - nlog($result); + $adhocArray = $api + ->subscriptions + ->adhoc($cgt->token, ['amount' => $amount, 'item_name' => 'purchase']); + + + nlog($adhocArray); // /*Refactor and push to BaseDriver*/ // if ($data['response'] != null && $data['response']->getMessages()->getResultCode() == 'Ok') { @@ -143,6 +148,44 @@ 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 ( $sort_data_before_merge ) { + ksort( $api_data ); + } + + // concatenate the array key value pairs. + $parameter_string = ''; + foreach ( $api_data as $key => $val ) { + + if ( $skip_empty_values && empty( $val ) ) { + continue; + } + + if ( 'signature' !== $key ) { + $val = urlencode( $val ); + $parameter_string .= "$key=$val&"; + } + } + // when not sorting passphrase should be added to the end before md5 + 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') ); + } else { + $parameter_string = rtrim( $parameter_string, '&' ); + } + + nlog($parameter_string); + + return $parameter_string; + + } + private function genSig($data) { $fields = []; diff --git a/app/PaymentDrivers/PayFastPaymentDriver.php b/app/PaymentDrivers/PayFastPaymentDriver.php index 6f56aebe9d3f..e2e5816a85c1 100644 --- a/app/PaymentDrivers/PayFastPaymentDriver.php +++ b/app/PaymentDrivers/PayFastPaymentDriver.php @@ -77,7 +77,7 @@ class PayFastPaymentDriver extends BaseDriver ] ); - } catch(Exception $e) { + } catch(\Exception $e) { echo '##PAYFAST## There was an exception: '.$e->getMessage(); @@ -161,6 +161,8 @@ class PayFastPaymentDriver extends BaseDriver } } + nlog(http_build_query($fields)); + return md5(http_build_query($fields)); } diff --git a/app/Services/Invoice/AutoBillInvoice.php b/app/Services/Invoice/AutoBillInvoice.php index 480ba0e7fb1c..df35431f42ea 100644 --- a/app/Services/Invoice/AutoBillInvoice.php +++ b/app/Services/Invoice/AutoBillInvoice.php @@ -105,7 +105,7 @@ class AutoBillInvoice extends AbstractService /* Build payment hash */ $payment_hash = PaymentHash::create([ - 'hash' => Str::random(128), + 'hash' => Str::random(64), 'data' => ['invoices' => [['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount]]], 'fee_total' => $fee, 'fee_invoice_id' => $this->invoice->id, diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index 99075a66151f..c7304c214f50 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -232,6 +232,9 @@ class HtmlEngine $data['$user.name'] = ['value' => $this->entity->user->present()->name(), 'label' => ctrans('texts.name')]; $data['$user.first_name'] = ['value' => $this->entity->user->first_name, 'label' => ctrans('texts.first_name')]; $data['$user.last_name'] = ['value' => $this->entity->user->last_name, 'label' => ctrans('texts.last_name')]; + $data['$created_by_user'] = &$data['$user.name']; + $data['$assigned_to_user'] = ['value' => $this->entity->assigned_user ? $this->entity->assigned_user->present()->name() : '', 'label' => ctrans('texts.name')]; + $data['$user_iban'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company1', $this->settings->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company1')]; $data['$invoice.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice1', $this->entity->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice1')]; $data['$invoice.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')]; diff --git a/database/migrations/2021_09_23_100629_add_currencies.php b/database/migrations/2021_09_23_100629_add_currencies.php new file mode 100644 index 000000000000..dd6187e4bab4 --- /dev/null +++ b/database/migrations/2021_09_23_100629_add_currencies.php @@ -0,0 +1,60 @@ + 105, 'name' => 'Gambia Dalasi', 'code' => 'GMD', 'symbol' => 'D', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], +['id' => 106, 'name' => 'Paraguayan Guarani', 'code' => 'PYG', 'symbol' => '₲', 'precision' => '0', 'thousand_separator' => ',', 'decimal_separator' => '.'], +['id' => 107, 'name' => 'Malawi Kwacha','code' => 'MWK', 'symbol' => 'MK', 'precision' => '2','thousand_separator' => ',', 'decimal_separator' => '.'], +['id' => 108, 'name' => 'Zimbabwean Dollar', 'code' => 'ZWL', 'symbol' => 'Z$', 'precision' => '0', 'thousand_separator' => ',', 'decimal_separator' => '.'], +['id' => 109, 'name' => 'Cambodian Riel', 'code' => 'KHR', 'symbol' => '៛', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], +['id' => 110, 'name' => 'Vanuatu Vatu','code' => 'VUV', 'symbol' => 'VT', 'precision' => '0','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); + } + } + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + } +} diff --git a/database/seeders/PaymentLibrariesSeeder.php b/database/seeders/PaymentLibrariesSeeder.php index 17a9ac173588..818431f7de96 100644 --- a/database/seeders/PaymentLibrariesSeeder.php +++ b/database/seeders/PaymentLibrariesSeeder.php @@ -97,7 +97,7 @@ class PaymentLibrariesSeeder extends Seeder Gateway::query()->update(['visible' => 0]); - Gateway::whereIn('id', [1,7,15,20,39,46,55,50,57])->update(['visible' => 1]); + Gateway::whereIn('id', [1,7,11,15,20,39,46,55,50,57])->update(['visible' => 1]); if (Ninja::isHosted()) { Gateway::whereIn('id', [20])->update(['visible' => 0]); diff --git a/resources/views/portal/ninja2020/auth/login.blade.php b/resources/views/portal/ninja2020/auth/login.blade.php index c8674eeb83a1..4dbeae512db3 100644 --- a/resources/views/portal/ninja2020/auth/login.blade.php +++ b/resources/views/portal/ninja2020/auth/login.blade.php @@ -77,7 +77,7 @@ @endif - @if(!empty($company->present()->website())) + @if(!is_null($company) && !empty($company->present()->website()))