Working on importing customers

This commit is contained in:
David Bomba 2024-03-18 12:58:42 +11:00
parent 48ac0a92d4
commit 86fc7a0662
11 changed files with 309 additions and 60 deletions

View File

@ -11,53 +11,54 @@
namespace App\Console\Commands;
use App\DataMapper\ClientRegistrationFields;
use App\DataMapper\CompanySettings;
use App\DataMapper\FeesAndLimits;
use App\Events\Invoice\InvoiceWasCreated;
use App\Events\RecurringInvoice\RecurringInvoiceWasCreated;
use App\Factory\GroupSettingFactory;
use App\Factory\InvoiceFactory;
use App\Factory\InvoiceItemFactory;
use App\Factory\RecurringInvoiceFactory;
use App\Factory\SubscriptionFactory;
use App\Helpers\Invoice\InvoiceSum;
use App\Jobs\Company\CreateCompanyTaskStatuses;
use App\Libraries\MultiDB;
use App\Models\Account;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Models\BankTransactionRule;
use stdClass;
use Carbon\Carbon;
use Faker\Factory;
use App\Models\Task;
use App\Models\User;
use App\Utils\Ninja;
use App\Models\Quote;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Company;
use App\Models\CompanyGateway;
use App\Models\CompanyToken;
use App\Models\Country;
use App\Models\Credit;
use App\Models\Vendor;
use App\Models\Account;
use App\Models\Company;
use App\Models\Country;
use App\Models\Expense;
use App\Models\Invoice;
use App\Models\Product;
use App\Models\Project;
use App\Models\Quote;
use App\Models\RecurringInvoice;
use App\Models\Task;
use App\Models\TaskStatus;
use App\Models\TaxRate;
use App\Models\User;
use App\Models\Vendor;
use App\Libraries\MultiDB;
use App\Models\TaskStatus;
use App\Models\CompanyToken;
use App\Models\ClientContact;
use App\Models\VendorContact;
use App\Repositories\InvoiceRepository;
use App\Utils\Ninja;
use App\Utils\Traits\GeneratesCounter;
use App\Models\CompanyGateway;
use App\Factory\InvoiceFactory;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Utils\Traits\MakesHash;
use Carbon\Carbon;
use Faker\Factory;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use App\Models\RecurringInvoice;
use App\DataMapper\FeesAndLimits;
use App\DataMapper\ClientSettings;
use App\DataMapper\CompanySettings;
use App\Factory\InvoiceItemFactory;
use App\Helpers\Invoice\InvoiceSum;
use App\Models\BankTransactionRule;
use App\Factory\GroupSettingFactory;
use App\Factory\SubscriptionFactory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Cache;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Support\Facades\Schema;
use stdClass;
use App\Repositories\InvoiceRepository;
use App\Factory\RecurringInvoiceFactory;
use App\Events\Invoice\InvoiceWasCreated;
use App\DataMapper\ClientRegistrationFields;
use App\Jobs\Company\CreateCompanyTaskStatuses;
use App\Events\RecurringInvoice\RecurringInvoiceWasCreated;
class CreateSingleAccount extends Command
{
@ -951,7 +952,7 @@ class CreateSingleAccount extends Command
}
if (config('ninja.testvars.paytrace.decrypted') && ($this->gateway == 'all' || $this->gateway == 'paytrace')) {
if (config('ninja.testvars.paytrace') && ($this->gateway == 'all' || $this->gateway == 'paytrace')) {
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
@ -960,7 +961,7 @@ class CreateSingleAccount extends Command
$cg->require_billing_address = true;
$cg->require_shipping_address = true;
$cg->update_details = true;
$cg->config = encrypt(config('ninja.testvars.paytrace.decrypted'));
$cg->config = encrypt(config('ninja.testvars.paytrace'));
$cg->save();
@ -1015,6 +1016,63 @@ class CreateSingleAccount extends Command
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.eway') && ($this->gateway == 'all' || $this->gateway == 'eway')) {
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = '944c20175bbe6b9972c05bcfe294c2c7';
$cg->require_cvv = true;
$cg->require_billing_address = true;
$cg->require_shipping_address = true;
$cg->update_details = true;
$cg->config = encrypt(config('ninja.testvars.eway'));
$cg->save();
$gateway_types = $cg->driver()->gatewayTypes();
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
if (config('ninja.testvars.gocardless') && ($this->gateway == 'all' || $this->gateway == 'gocardless')) {
$c_settings = ClientSettings::defaults();
$c_settings->currency_id = '2';
$client = Client::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'name' => 'cypress',
'country_id' => 826,
'settings' => $c_settings
]);
$cg = new CompanyGateway();
$cg->company_id = $company->id;
$cg->user_id = $user->id;
$cg->gateway_key = 'b9886f9257f0c6ee7c302f1c74475f6c';
$cg->require_cvv = true;
$cg->require_billing_address = true;
$cg->require_shipping_address = true;
$cg->update_details = true;
$cg->config = encrypt(config('ninja.testvars.gocardless'));
$cg->save();
$gateway_types = $cg->driver($client)->gatewayTypes();
$fees_and_limits = new stdClass();
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits();
$cg->fees_and_limits = $fees_and_limits;
$cg->save();
}
}
private function createRecurringInvoice(Client $client)

View File

@ -23,6 +23,7 @@ use App\Http\Requests\CompanyGateway\StoreCompanyGatewayRequest;
use App\Http\Requests\CompanyGateway\TestCompanyGatewayRequest;
use App\Http\Requests\CompanyGateway\UpdateCompanyGatewayRequest;
use App\Jobs\Util\ApplePayDomain;
use App\Libraries\MultiDB;
use App\Models\Client;
use App\Models\CompanyGateway;
use App\PaymentDrivers\CheckoutCom\CheckoutSetupWebhook;
@ -544,4 +545,15 @@ class CompanyGatewayController extends BaseController
}
public function importCustomers(TestCompanyGatewayRequest $request, CompanyGateway $company_gateway)
{
dispatch(function () use($company_gateway) {
MultiDB::setDb($company_gateway->company->db);
$company_gateway->driver()->importCustomers();
})->afterResponse();
return response()->json(['message' => ctrans('texts.import_started')], 200);
}
}

View File

@ -494,7 +494,7 @@ class Account extends BaseModel
return 0;
}
if (Carbon::createFromTimestamp($this->created_at)->diffInWeeks() == 0) {
if (Carbon::createFromTimestamp($this->created_at)->diffInWeeks() <= 1) {
return 20;
}

View File

@ -132,6 +132,7 @@ class CompanyGateway extends BaseModel
// const TYPE_EWAY = 313;
// const TYPE_FORTE = 314;
// const PAYPAL_PPCP = 323;
// const SQUARE = 320;
public $gateway_consts = [
'38f2c48af60c7dd69e04248cbb24c36e' => 300,
@ -144,7 +145,7 @@ class CompanyGateway extends BaseModel
'8fdeed552015b3c7b44ed6c8ebd9e992' => 309,
'd6814fc83f45d2935e7777071e629ef9' => 310,
'bbd736b3254b0aabed6ad7fda1298c88' => 311,
'1bd651fb213ca0c9d66ae3c336dc77e7' => 312,
'1bd651fb213ca0c9d66ae3c336dc77e8' => 312,
'944c20175bbe6b9972c05bcfe294c2c7' => 313,
'kivcvjexxvdiyqtj3mju5d6yhpeht2xs' => 314,
'65faab2ab6e3223dbe848b1686490baz' => 320,

View File

@ -193,9 +193,16 @@ class AuthorizePaymentDriver extends BaseDriver
public function import()
{
$this->init();
return (new AuthorizeCustomer($this))->importCustomers();
}
public function importCustomers()
{
return $this->import();
}
public function auth(): bool
{
return $this->init()->getPublicClientKey() ?? false;

View File

@ -811,4 +811,9 @@ class BaseDriver extends AbstractPaymentDriver
{
return true;
}
public function importCustomers()
{
}
}

View File

@ -12,29 +12,39 @@
namespace App\PaymentDrivers;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use Exception;
use App\Models\Client;
use Braintree\Gateway;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\SystemLog;
use App\Models\GatewayType;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\Models\ClientContact;
use App\Factory\ClientFactory;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken;
use App\Factory\ClientContactFactory;
use App\PaymentDrivers\Braintree\ACH;
use App\PaymentDrivers\Braintree\CreditCard;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Database\QueryException;
use App\PaymentDrivers\Braintree\PayPal;
use Braintree\Gateway;
use Exception;
use Illuminate\Support\Facades\Validator;
use App\PaymentDrivers\Braintree\CreditCard;
class BraintreePaymentDriver extends BaseDriver
{
use GeneratesCounter;
public $refundable = true;
public $token_billing = true;
public $can_authorise_credit_card = true;
private bool $completed = true;
/**
* @var Gateway;
*/
@ -304,7 +314,7 @@ class BraintreePaymentDriver extends BaseDriver
try {
$ct =$this->init()->gateway->clientToken()->generate();
nlog($ct);
return true;
}
catch(\Exception $e) {
@ -313,4 +323,165 @@ class BraintreePaymentDriver extends BaseDriver
return false;
}
private function find(string $customer_id = '') {
try {
return $this->init()->gateway->customer()->find($customer_id);
}
catch(\Exception $e){
return false;
}
return false;
}
private function findTokens(string $gateway_customer_reference)
{
return ClientGatewayToken::where('company_id', $this->company_gateway->company_id)
->where('gateway_customer_reference', $gateway_customer_reference)
->exists();
}
private function findContact(string $email) {
return ClientContact::where('company_id', $this->company_gateway->company_id)
->where('email', $email)
->first()->client ?? false;
}
private function addClientCards(Client $client, array $cards)
{
$this->client = $client;
foreach($cards as $card) {
$payment_meta = new \stdClass();
$payment_meta->exp_month = (string) $card->expirationMonth;
$payment_meta->exp_year = (string) $card->expirationYear;
$payment_meta->brand = (string) $card->cardType;
$payment_meta->last4 = (string) $card->last4;
$payment_meta->type = GatewayType::CREDIT_CARD;
$data = [
'payment_meta' => $payment_meta,
'token' => $card->token,
'payment_method_id' => GatewayType::CREDIT_CARD,
];
$this->storeGatewayToken($data, ['gateway_customer_reference' => $card->customerId]);
nlog("adding card to customer payment profile");
}
}
public function createNinjaClient(mixed $customer): Client
{
$client = ClientFactory::create($this->company_gateway->company_id, $this->company_gateway->user_id);
$b_business_address = count($customer->addresses) >= 1 ? $customer->addresses[0] : false;
$b_shipping_address = count($customer->addresses) > 1 ? $customer->addresses[1] : false;
$import_client_data = [];
if($b_business_address) {
$braintree_address =
[
'address1' => $b_business_address->extendedAddress ?? '',
'address2' => $b_business_address->streetAddress ?? '',
'city' => $b_business_address->locality ?? '',
'postal_code' => $b_business_address->postalCode ?? '',
'state' => $b_business_address->region ?? '',
'country_id' => $b_business_address->countryCodeNumeric ?? '840',
];
$import_client_data = array_merge($import_client_data, $braintree_address);
}
if($b_shipping_address) {
$braintree_shipping_address =
[
'shipping_address1' => $b_shipping_address->extendedAddress ?? '',
'shipping_address2' => $b_shipping_address->streetAddress ?? '',
'shipping_city' => $b_shipping_address->locality ?? '',
'shipping_postal_code' => $b_shipping_address->postalCode ?? '',
'shipping_state' => $b_shipping_address->region ?? '',
'shipping_country_id' => $b_shipping_address->countryCodeNumeric ?? '840',
];
$import_client_data = array_merge($import_client_data, $braintree_shipping_address);
}
$client->fill($import_client_data);
$client->phone = $customer->phone ?? '';
$client->name = $customer->company ?? $customer->firstName;
$settings = $client->settings;
$settings->currency_id = (string) $this->company_gateway->company->settings->currency_id;
$client->settings = $settings;
$client->save();
$contact = ClientContactFactory::create($this->company_gateway->company_id, $this->company_gateway->user_id);
$contact->first_name = $customer->firstName ?? '';
$contact->last_name = $customer->lastName ?? '';
$contact->email = $customer->email ?? '';
$contact->phone = $customer->phone ?? '';
$contact->client_id = $client->id;
$contact->saveQuietly();
if (! isset($client->number) || empty($client->number)) {
$x = 1;
do {
try {
$client->number = $this->getNextClientNumber($client);
$client->saveQuietly();
$this->completed = false;
} catch (QueryException $e) {
$x++;
if ($x > 10) {
$this->completed = false;
}
}
} while ($this->completed);
} else {
$client->saveQuietly();
}
return $client;
}
public function importCustomers()
{
$customers = $this->init()->gateway->customer()->all();
foreach($customers as $c){
$customer = $this->find($c->id);
if(!$customer)
continue;
if(!$this->findTokens($c->id) && !($client = $this->findContact($customer->email))) {
//customer is not referenced in the system - create client
$client = $this->createNinjaClient($customer);
nlog("Creating new Client");
}
$this->addClientCards($client, $customer->creditCards);
nlog("Adding Braintree Client: {$c->id} => {$client->id}");
}
}
}

View File

@ -84,11 +84,11 @@ class GoCardlessPaymentDriver extends BaseDriver
$types[] = GatewayType::DIRECT_DEBIT;
}
if (in_array($this->client->currency()->code, ['EUR', 'GBP'])) {
if ($this->client && in_array($this->client->currency()->code, ['EUR', 'GBP'])) {
$types[] = GatewayType::SEPA;
}
if ($this->client->currency()->code === 'GBP') {
if ($this->client && $this->client->currency()->code === 'GBP') {
$types[] = GatewayType::INSTANT_BANK_PAY;
}

View File

@ -62,12 +62,6 @@ class ImportCustomers
$this->addCustomer($customer);
}
//handle
// if(is_array($customers->data) && end($customers->data) && array_key_exists('id', end($customers->data)))
// $starting_after = end($customers->data)['id'];
// else
// break;
$starting_after = isset(end($customers->data)['id']) ? end($customers->data)['id'] : false;
if (!$starting_after) {

View File

@ -84,6 +84,11 @@ return [
'username' => 'user@example.com',
'clientname' => 'client@example.com',
'password' => 'password',
'gocardless' => env('GOCARDLESS_KEYS',''),
'square' => env('SQUARE_KEYS',''),
'eway' => env('EWAY_KEYS',''),
'mollie', env('MOLLIE_KEYS',''),
'paytrace' => env('PAYTRACE_KEYS',''),
'stripe' => env('STRIPE_KEYS', ''),
'paypal' => env('PAYPAL_KEYS', ''),
'ppcp' => env('PPCP_KEYS', ''),
@ -94,11 +99,6 @@ return [
'test_email' => env('TEST_EMAIL', 'test@example.com'),
'wepay' => env('WEPAY_KEYS', ''),
'braintree' => env('BRAINTREE_KEYS', ''),
'paytrace' => [
'username' => env('PAYTRACE_U', ''),
'password' => env('PAYTRACE_P', ''),
'decrypted' => env('PAYTRACE_KEYS', ''),
],
'mollie' => env('MOLLIE_KEYS', ''),
'square' => env('SQUARE_KEYS', ''),
],

View File

@ -198,6 +198,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
Route::post('company_gateways/bulk', [CompanyGatewayController::class, 'bulk'])->name('company_gateways.bulk');
Route::post('company_gateways/{company_gateway}/test', [CompanyGatewayController::class, 'test'])->name('company_gateways.test');
Route::post('company_gateways/{company_gateway}/import_customers', [CompanyGatewayController::class, 'importCustomers'])->name('company_gateways.import_customers');
Route::put('company_users/{user}', [CompanyUserController::class, 'update']);
Route::put('company_users/{user}/preferences', [CompanyUserController::class, 'updatePreferences']);