diff --git a/app/Import/Providers/BaseImport.php b/app/Import/Providers/BaseImport.php index f421bb9ea3f4..995c759fff64 100644 --- a/app/Import/Providers/BaseImport.php +++ b/app/Import/Providers/BaseImport.php @@ -13,6 +13,8 @@ namespace App\Import\Providers; use App\Import\ImportException; use App\Models\Company; use App\Models\User; +use App\Repositories\InvoiceRepository; +use App\Utils\Traits\CleanLineItems; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; @@ -23,6 +25,8 @@ use Symfony\Component\HttpFoundation\ParameterBag; class BaseImport { + use CleanLineItems; + public Company $company; public array $request; @@ -55,17 +59,6 @@ class BaseImport { auth()->user()->setCompany($this->company); } - protected function findUser( $user_hash ) { - $user = User::where( 'account_id', $this->company->account_id ) - ->where( DB::raw( 'CONCAT_WS(" ", first_name, last_name)' ), 'like', '%' . $user_hash . '%' ) - ->first(); - - if ( $user ) { - return $user->id; - } else { - return $this->company->owner()->id; - } - } protected function getCsvData( $entity_type ) { @@ -127,6 +120,8 @@ class BaseImport { public function ingest($data, $entity_type) { + $count = 0; + foreach ( $data as $record ) { try { $entity = $this->transformer->transform( $record ); @@ -148,6 +143,7 @@ class BaseImport { $this->factory_name::create( $this->company->id, $this->getUserIDForRecord( $entity ) ) ); $entity->saveQuietly(); + $count++; } } catch ( \Exception $ex ) { @@ -160,7 +156,151 @@ class BaseImport { $this->error_array[ $entity_type ][] = [ $entity_type => $record, 'error' => $message ]; } + + return $count; } } + public function ingestInvoices( $invoices ) { + $invoice_transformer = $this->transformer; + + /** @var PaymentRepository $payment_repository */ + $payment_repository = app()->make( PaymentRepository::class ); + $payment_repository->import_mode = true; + + /** @var ClientRepository $client_repository */ + $client_repository = app()->make( ClientRepository::class ); + $client_repository->import_mode = true; + + $invoice_repository = new InvoiceRepository(); + $invoice_repository->import_mode = true; + + foreach ( $invoices as $raw_invoice ) { + try { + $invoice_data = $invoice_transformer->transform( $raw_invoice ); + + $invoice_data['line_items'] = $this->cleanItems( $invoice_data['line_items'] ?? [] ); + + + // If we don't have a client ID, but we do have client data, go ahead and create the client. + if ( empty( $invoice_data['client_id'] ) && ! empty( $invoice_data['client'] ) ) { + $client_data = $invoice_data['client']; + $client_data['user_id'] = $this->getUserIDForRecord( $invoice_data ); + + $client_repository->save( + $client_data, + $client = ClientFactory::create( $this->company->id, $client_data['user_id'] ) + ); + $invoice_data['client_id'] = $client->id; + unset( $invoice_data['client'] ); + } + + $validator = Validator::make( $invoice_data, ( new StoreInvoiceRequest() )->rules() ); + if ( $validator->fails() ) { + $this->error_array['invoice'][] = + [ 'invoice' => $invoice_data, 'error' => $validator->errors()->all() ]; + } else { + $invoice = InvoiceFactory::create( $this->company->id, $this->getUserIDForRecord( $invoice_data ) ); + if ( ! empty( $invoice_data['status_id'] ) ) { + $invoice->status_id = $invoice_data['status_id']; + } + $invoice_repository->save( $invoice_data, $invoice ); + $this->addInvoiceToMaps( $invoice ); + + // If we're doing a generic CSV import, only import payment data if we're not importing a payment CSV. + // If we're doing a platform-specific import, trust the platform to only return payment info if there's not a separate payment CSV. + if ( $this->import_type !== 'csv' || empty( $this->column_map['payment'] ) ) { + // Check for payment columns + if ( ! empty( $invoice_data['payments'] ) ) { + foreach ( $invoice_data['payments'] as $payment_data ) { + $payment_data['user_id'] = $invoice->user_id; + $payment_data['client_id'] = $invoice->client_id; + $payment_data['invoices'] = [ + [ + 'invoice_id' => $invoice->id, + 'amount' => $payment_data['amount'] ?? null, + ], + ]; + + /* Make sure we don't apply any payments to invoices with a Zero Amount*/ + if($invoice->amount > 0) + { + $payment_repository->save( + $payment_data, + PaymentFactory::create( $this->company->id, $invoice->user_id, $invoice->client_id ) + ); + } + } + } + } + + $this->actionInvoiceStatus( $invoice, $invoice_data, $invoice_repository ); + } + } catch ( \Exception $ex ) { + if ( $ex instanceof ImportException ) { + $message = $ex->getMessage(); + } else { + report( $ex ); + $message = 'Unknown error'; + } + + $this->error_array['invoice'][] = [ 'invoice' => $raw_invoice, 'error' => $message ]; + } + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + protected function getUserIDForRecord( $record ) { + if ( ! empty( $record['user_id'] ) ) { + return $this->findUser( $record['user_id'] ); + } else { + return $this->company->owner()->id; + } + } + + protected function findUser( $user_hash ) { + $user = User::where( 'account_id', $this->company->account->id ) + ->where( \DB::raw( 'CONCAT_WS(" ", first_name, last_name)' ), 'like', '%' . $user_hash . '%' ) + ->first(); + + if ( $user ) { + return $user->id; + } else { + return $this->company->owner()->id; + } + } + } diff --git a/app/Import/Providers/Csv.php b/app/Import/Providers/Csv.php index 6c516f5b0089..0eee3c42a85c 100644 --- a/app/Import/Providers/Csv.php +++ b/app/Import/Providers/Csv.php @@ -11,24 +11,34 @@ namespace App\Import\Providers; use App\Factory\ClientFactory; +use App\Factory\InvoiceFactory; +use App\Factory\ProductFactory; use App\Http\Requests\Client\StoreClientRequest; +use App\Http\Requests\Invoice\StoreInvoiceRequest; +use App\Http\Requests\Product\StoreProductRequest; use App\Import\ImportException; use App\Import\Providers\BaseImport; use App\Import\Providers\ImportInterface; use App\Import\Transformer\Csv\ClientTransformer; +use App\Import\Transformer\Csv\ProductTransformer; use App\Repositories\ClientRepository; +use App\Repositories\InvoiceRepository; +use App\Repositories\ProductRepository; use Illuminate\Support\Facades\Validator; use Symfony\Component\HttpFoundation\ParameterBag; class Csv extends BaseImport implements ImportInterface { + public array $entity_count = []; + public function import(string $entity) { if(in_array($entity, [ 'client', 'product', 'invoice', 'payment', 'vendor', 'expense' ])) - $this->{$entity}; + $this->{$entity}(); + //collate any errors } private function client() @@ -38,10 +48,13 @@ class Csv extends BaseImport implements ImportInterface $data = $this->getCsvData($entity_type); - $data = $this->preTransform($data); + $data = $this->preTransform($data, $entity_type); - if(empty($data)) + if(empty($data)){ + + $this->entity_count['clients'] = 0; return; + } $this->request_name = StoreClientRequest::class; $this->repository_name = ClientRepository::class; @@ -52,19 +65,78 @@ class Csv extends BaseImport implements ImportInterface $this->transformer = new ClientTransformer($this->company); - $this->ingest($data, $entity_type); + $client_count = $this->ingest($data, $entity_type); + + $this->entity_count['clients'] = $client_count; + + } + + private function product() + { + + $entity_type = 'product'; + + $data = $this->getCsvData($entity_type); + + $data = $this->preTransform($data, $entity_type); + + if(empty($data)){ + + $this->entity_count['products'] = 0; + return; + } + + $this->request_name = StoreProductRequest::class; + $this->repository_name = ProductRepository::class; + $this->factory_name = ProductFactory::class; + + $this->repository = app()->make( $this->repository_name ); + $this->repository->import_mode = true; + + $this->transformer = new ProductTransformer($this->company); + + $product_count = $this->ingest($data, $entity_type); + + $this->entity_count['products'] = $product_count; + + } + + private function invoice() + { + + $entity_type = 'invoice'; + + $data = $this->getCsvData($entity_type); + + $data = $this->preTransform($data, $entity_type); + + if(empty($data)){ + + $this->entity_count['invoices'] = 0; + return; + } + + $this->request_name = StoreInvoiceRequest::class; + $this->repository_name = InvoiceRepository::class; + $this->factory_name = InvoiceFactory::class; + + $this->repository = app()->make( $this->repository_name ); + $this->repository->import_mode = true; + + $this->transformer = new ProductTransformer($this->company); + + $invoice_count = $this->ingest($data, $entity_type); + + $this->entity_count['invoices'] = $invoice_count; } - - - - public function preTransform(array $data) + public function preTransform(array $data, $entity_type) { - if ( empty( $this->column_map[ 'client' ] ) ) { + if ( empty( $this->column_map[ $entity_type ] ) ) { return false; } @@ -73,7 +145,7 @@ class Csv extends BaseImport implements ImportInterface } //sort the array by key - $keys = $this->column_map[ 'client' ]; + $keys = $this->column_map[ $entity_type ]; ksort( $keys ); $data = array_map( function ( $row ) use ( $keys ) { diff --git a/app/Import/Providers/ImportInterface.php b/app/Import/Providers/ImportInterface.php index e757dae58cb0..1bf6b78d3b1b 100644 --- a/app/Import/Providers/ImportInterface.php +++ b/app/Import/Providers/ImportInterface.php @@ -15,7 +15,7 @@ interface ImportInterface public function import(string $entity); - public function preTransform(array $data); + public function preTransform(array $data, string $entity_type); public function transform(array $data); } \ No newline at end of file diff --git a/app/Import/Transformer/BaseTransformer.php b/app/Import/Transformer/BaseTransformer.php index 72ae3bf8b8ac..ca6d2a038ece 100644 --- a/app/Import/Transformer/BaseTransformer.php +++ b/app/Import/Transformer/BaseTransformer.php @@ -14,6 +14,7 @@ namespace App\Import\Transformer; use App\Models\ClientContact; use App\Models\Country; use App\Models\PaymentType; +use App\Models\User; use App\Utils\Number; use Exception; use Illuminate\Support\Carbon; @@ -348,4 +349,6 @@ class BaseTransformer return $pt ? $pt->id : null; } + + } diff --git a/app/Import/Transformer/Csv/ClientTransformer.php b/app/Import/Transformer/Csv/ClientTransformer.php index 3659a3b6a141..4df6591ff63d 100644 --- a/app/Import/Transformer/Csv/ClientTransformer.php +++ b/app/Import/Transformer/Csv/ClientTransformer.php @@ -78,3 +78,5 @@ class ClientTransformer extends BaseTransformer ]; } } + + diff --git a/app/Import/Transformer/Csv/InvoiceTransformer.php b/app/Import/Transformer/Csv/InvoiceTransformer.php new file mode 100644 index 000000000000..d182e4cadb0a --- /dev/null +++ b/app/Import/Transformer/Csv/InvoiceTransformer.php @@ -0,0 +1,129 @@ +hasInvoice( $invoice_data['invoice.number'] ) ) { + throw new ImportException( 'Invoice number already exists' ); + } + + $invoiceStatusMap = [ + 'sent' => Invoice::STATUS_SENT, + 'draft' => Invoice::STATUS_DRAFT, + ]; + + $transformed = [ + 'company_id' => $this->company->id, + 'number' => $this->getString( $invoice_data, 'invoice.number' ), + 'user_id' => $this->getString( $invoice_data, 'invoice.user_id' ), + 'amount' => $amount = $this->getFloat( $invoice_data, 'invoice.amount' ), + 'balance' => isset( $invoice_data['invoice.balance'] ) ? $this->getFloat( $invoice_data, 'invoice.balance' ) : $amount, + 'client_id' => $this->getClient( $this->getString( $invoice_data, 'client.name' ), $this->getString( $invoice_data, 'client.email' ) ), + 'discount' => $this->getFloat( $invoice_data, 'invoice.discount' ), + 'po_number' => $this->getString( $invoice_data, 'invoice.po_number' ), + 'date' => isset( $invoice_data['invoice.date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['invoice.date'] ) ) : now()->format('Y-m-d'), + 'due_date' => isset( $invoice_data['invoice.due_date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['invoice.due_date'] ) ) : null, + 'terms' => $this->getString( $invoice_data, 'invoice.terms' ), + 'public_notes' => $this->getString( $invoice_data, 'invoice.public_notes' ), + 'private_notes' => $this->getString( $invoice_data, 'invoice.private_notes' ), + 'tax_name1' => $this->getString( $invoice_data, 'invoice.tax_name1' ), + 'tax_rate1' => $this->getFloat( $invoice_data, 'invoice.tax_rate1' ), + 'tax_name2' => $this->getString( $invoice_data, 'invoice.tax_name2' ), + 'tax_rate2' => $this->getFloat( $invoice_data, 'invoice.tax_rate2' ), + 'tax_name3' => $this->getString( $invoice_data, 'invoice.tax_name3' ), + 'tax_rate3' => $this->getFloat( $invoice_data, 'invoice.tax_rate3' ), + 'custom_value1' => $this->getString( $invoice_data, 'invoice.custom_value1' ), + 'custom_value2' => $this->getString( $invoice_data, 'invoice.custom_value2' ), + 'custom_value3' => $this->getString( $invoice_data, 'invoice.custom_value3' ), + 'custom_value4' => $this->getString( $invoice_data, 'invoice.custom_value4' ), + 'footer' => $this->getString( $invoice_data, 'invoice.footer' ), + 'partial' => $this->getFloat( $invoice_data, 'invoice.partial' ), + 'partial_due_date' => $this->getString( $invoice_data, 'invoice.partial_due_date' ), + 'custom_surcharge1' => $this->getString( $invoice_data, 'invoice.custom_surcharge1' ), + 'custom_surcharge2' => $this->getString( $invoice_data, 'invoice.custom_surcharge2' ), + 'custom_surcharge3' => $this->getString( $invoice_data, 'invoice.custom_surcharge3' ), + 'custom_surcharge4' => $this->getString( $invoice_data, 'invoice.custom_surcharge4' ), + 'exchange_rate' => $this->getString( $invoice_data, 'invoice.exchange_rate' ), + 'status_id' => $invoiceStatusMap[ $status = + strtolower( $this->getString( $invoice_data, 'invoice.status' ) ) ] ?? + Invoice::STATUS_SENT, + 'archived' => $status === 'archived', + ]; + + if ( isset( $invoice_data['payment.amount'] ) ) { + $transformed['payments'] = [ + [ + 'date' => isset( $invoice_data['payment.date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['payment.date'] ) ) : date( 'y-m-d' ), + 'transaction_reference' => $this->getString( $invoice_data, 'payment.transaction_reference' ), + 'amount' => $this->getFloat( $invoice_data, 'payment.amount' ), + ], + ]; + } elseif ( $status === 'paid' ) { + $transformed['payments'] = [ + [ + 'date' => isset( $invoice_data['payment.date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['payment.date'] ) ) : date( 'y-m-d' ), + 'transaction_reference' => $this->getString( $invoice_data, 'payment.transaction_reference' ), + 'amount' => $this->getFloat( $invoice_data, 'invoice.amount' ), + ], + ]; + } elseif ( isset( $transformed['amount'] ) && isset( $transformed['balance'] ) && ($transformed['amount'] != $transformed['balance'])) { + $transformed['payments'] = [ + [ + 'date' => isset( $invoice_data['payment.date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['payment.date'] ) ) : date( 'y-m-d' ), + 'transaction_reference' => $this->getString( $invoice_data, 'payment.transaction_reference' ), + 'amount' => $transformed['amount'] - $transformed['balance'], + ], + ]; + } + + $line_items = []; + foreach ( $line_items_data as $record ) { + $line_items[] = [ + 'quantity' => $this->getFloat( $record, 'item.quantity' ), + 'cost' => $this->getFloat( $record, 'item.cost' ), + 'product_key' => $this->getString( $record, 'item.product_key' ), + 'notes' => $this->getString( $record, 'item.notes' ), + 'discount' => $this->getFloat( $record, 'item.discount' ), + 'is_amount_discount' => filter_var( $this->getString( $record, 'item.is_amount_discount' ), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ), + 'tax_name1' => $this->getString( $record, 'item.tax_name1' ), + 'tax_rate1' => $this->getFloat( $record, 'item.tax_rate1' ), + 'tax_name2' => $this->getString( $record, 'item.tax_name2' ), + 'tax_rate2' => $this->getFloat( $record, 'item.tax_rate2' ), + 'tax_name3' => $this->getString( $record, 'item.tax_name3' ), + 'tax_rate3' => $this->getFloat( $record, 'item.tax_rate3' ), + 'custom_value1' => $this->getString( $record, 'item.custom_value1' ), + 'custom_value2' => $this->getString( $record, 'item.custom_value2' ), + 'custom_value3' => $this->getString( $record, 'item.custom_value3' ), + 'custom_value4' => $this->getString( $record, 'item.custom_value4' ), + 'type_id' => $this->getInvoiceTypeId( $record, 'item.type_id' ), + ]; + } + $transformed['line_items'] = $line_items; + + return $transformed; + } +} diff --git a/app/Import/Transformer/Csv/ProductTransformer.php b/app/Import/Transformer/Csv/ProductTransformer.php new file mode 100644 index 000000000000..f89bdc385bec --- /dev/null +++ b/app/Import/Transformer/Csv/ProductTransformer.php @@ -0,0 +1,46 @@ + $this->company->id, + 'product_key' => $this->getString($data, 'product.product_key'), + 'notes' => $this->getString($data, 'product.notes'), + 'cost' => $this->getFloat($data, 'product.cost'), + 'price' => $this->getFloat($data, 'product.price'), + 'quantity' => $this->getFloat($data, 'product.quantity'), + 'tax_name1' => $this->getString($data, 'product.tax_name1'), + 'tax_rate1' => $this->getFloat($data, 'product.tax_rate1'), + 'tax_name2' => $this->getString($data, 'product.tax_name2'), + 'tax_rate2' => $this->getFloat($data, 'product.tax_rate2'), + 'tax_name3' => $this->getString($data, 'product.tax_name3'), + 'tax_rate3' => $this->getFloat($data, 'product.tax_rate3'), + 'custom_value1' => $this->getString($data, 'product.custom_value1'), + 'custom_value2' => $this->getString($data, 'product.custom_value2'), + 'custom_value3' => $this->getString($data, 'product.custom_value3'), + 'custom_value4' => $this->getString($data, 'product.custom_value4'), + ]; + } +} diff --git a/app/Jobs/Ninja/CompanySizeCheck.php b/app/Jobs/Ninja/CompanySizeCheck.php index ea1dd2efaa84..79a530d1eb01 100644 --- a/app/Jobs/Ninja/CompanySizeCheck.php +++ b/app/Jobs/Ninja/CompanySizeCheck.php @@ -54,16 +54,31 @@ class CompanySizeCheck implements ShouldQueue private function check() { - Company::cursor()->each(function ($company) { - if ($company->invoices()->count() > 500 || $company->products()->count() > 500 || $company->clients()->count() > 500) { - - nlog("Marking company {$company->id} as large"); - - $company->is_large = true; - $company->save(); - } + Company::where('is_large', false)->withCount(['invoices','clients','products'])->cursor()->each(function ($company){ - }); + if ($company->invoices_count > 500 || $company->products_count > 500 || $company->clients_count > 500) + { + + nlog("Marking company {$company->id} as large"); + + $company->account->companies()->update(['is_large' => true]); + + } + + + }); + + // Company::where('is_large', false)->cursor()->each(function ($company) { + + // if ($company->invoices()->count() > 500 || $company->products()->count() > 500 || $company->clients()->count() > 500) { + + // nlog("Marking company {$company->id} as large"); + + // $company->account->companies->update(['is_large' => true]) + + // } + + // }); } } diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index 24de8b99f883..d21724365751 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -65,10 +65,15 @@ class SendRecurring implements ShouldQueue // Generate Standard Invoice $invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client); - if($this->recurring_invoice->auto_bill == "always") + if($this->recurring_invoice->auto_bill === "always"){ $invoice->auto_bill_enabled = true; - elseif($this->recurring_invoice->auto_bill == "off") + } + elseif($this->recurring_invoice->auto_bill === "optout" || $this->recurring_invoice->auto_bill === "optin"){ + + } + elseif($this->recurring_invoice->auto_bill === "off"){ $invoice->auto_bill_enabled = false; + } $invoice->date = now()->format('Y-m-d'); $invoice->due_date = $this->recurring_invoice->calculateDueDate(now()->format('Y-m-d')); diff --git a/tests/Feature/Import/CSV/BaseTransformerTest.php b/tests/Feature/Import/CSV/BaseTransformerTest.php index 8d0a75583de8..f00cdf8382cd 100644 --- a/tests/Feature/Import/CSV/BaseTransformerTest.php +++ b/tests/Feature/Import/CSV/BaseTransformerTest.php @@ -18,6 +18,7 @@ use App\Models\Expense; use App\Models\Invoice; use App\Models\Payment; use App\Models\Product; +use App\Models\TaxRate; use App\Models\Vendor; use App\Utils\Traits\MakesHash; use Illuminate\Routing\Middleware\ThrottleRequests; @@ -105,9 +106,12 @@ class BaseTransformerTest extends TestCase $this->assertEquals($client->id, $base_transformer->getClient(null, 'test@gmail.com')); $this->assertNull($base_transformer->getClient('null', 'notest@gmail.com')); + $this->assertEquals($client->id, $base_transformer->getClientId(' magic')); + $this->assertEquals($client->id, $base_transformer->getClientId('Magic ')); + } - public function testHasClient() + public function testGetContact() { $base_transformer = new BaseTransformer($this->company); @@ -118,6 +122,32 @@ class BaseTransformerTest extends TestCase 'name' => 'magic ', ]); + $contact = ClientContact::factory()->create([ + 'user_id' => $this->user->id, + 'client_id' => $client->id, + 'company_id' => $this->company->id, + 'is_primary' => 1, + 'send_email' => true, + 'email' => 'test@gmail.com' + ]); + + $this->assertEquals($contact->id, $base_transformer->getContact('TeSt@gmail.com')->id); + $this->assertEquals($contact->id, $base_transformer->getContact('TeSt@gmail.com ')->id); + $this->assertEquals($contact->id, $base_transformer->getContact('TeSt@gmaiL.com')->id); + + } + + public function testHasClient() + { + $base_transformer = new BaseTransformer($this->company); + + $client = Client::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'id_number' => 'hit', + 'name' => 'maGic ', + ]); + $this->assertTrue($base_transformer->hasClient("magic")); $this->assertTrue($base_transformer->hasClient("Magic")); @@ -125,6 +155,161 @@ class BaseTransformerTest extends TestCase } + public function testHasVendor() + { + $base_transformer = new BaseTransformer($this->company); + + $client = Vendor::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'id_number' => 'hit', + 'name' => 'maGic ', + ]); + + + $this->assertTrue($base_transformer->hasVendor("magic")); + $this->assertTrue($base_transformer->hasVendor("Magic")); + $this->assertTrue($base_transformer->hasVendor("Ma gi c ")); + + } + + public function testHasProduct() + { + $base_transformer = new BaseTransformer($this->company); + + $client = Product::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'product_key' => 'HiT ', + ]); + + + $this->assertTrue($base_transformer->hasProduct("hit")); + $this->assertTrue($base_transformer->hasProduct(" hIt")); + $this->assertTrue($base_transformer->hasProduct(" h i T ")); + + } + + + + public function testGetCountryId() + { + $base_transformer = new BaseTransformer($this->company); + + $this->assertEquals(840, $base_transformer->getCountryId("us")); + $this->assertEquals(840, $base_transformer->getCountryId("US")); + $this->assertEquals(840, $base_transformer->getCountryId("United States")); + + } + + + public function testGetTaxRate() + { + $base_transformer = new BaseTransformer($this->company); + + $client = TaxRate::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'rate' => '10', + 'name' => 'GST' + ]); + + $this->assertEquals(10, $base_transformer->getTaxRate("gst")); + $this->assertEquals(10, $base_transformer->getTaxRate(" GST")); + $this->assertEquals(10, $base_transformer->getTaxRate(" gS t ")); + + } + + + public function testGetTaxName() + { + $base_transformer = new BaseTransformer($this->company); + + $client = TaxRate::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'rate' => '17.5', + 'name' => 'VAT' + ]); + + $this->assertEquals("VAT", $base_transformer->getTaxName("vat")); + $this->assertEquals("VAT", $base_transformer->getTaxName(" VaT")); + $this->assertEquals("VAT", $base_transformer->getTaxName(" va T ")); + + } + + public function testGetInvoiceId() + { + $base_transformer = new BaseTransformer($this->company); + + $invoice = Invoice::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'client_id' => $this->client->id, + 'number' => 'trick_number_123', + ]); + + $this->assertEquals($invoice->id, $base_transformer->getInvoiceId("TRICK_number_123")); + $this->assertEquals($invoice->id, $base_transformer->getInvoiceId(" TRICK_number_123")); + $this->assertEquals($invoice->id, $base_transformer->getInvoiceId(" TRICK_number_123 ")); + + } + + + + public function testHasInvoiceWithNumber() + { + $base_transformer = new BaseTransformer($this->company); + + $client = Invoice::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'client_id' => $this->client->id, + 'number' => 'tricky_number_123', + ]); + + $this->assertTrue($base_transformer->hasInvoice("TRICKY_number_123")); + $this->assertTrue($base_transformer->hasInvoice(" TRICKY_number_123")); + $this->assertTrue($base_transformer->hasInvoice(" TRICKY_number_123 ")); + + } + public function testInvoiceClientId() + { + $base_transformer = new BaseTransformer($this->company); + + $client = Invoice::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'client_id' => $this->client->id, + 'number' => 'tricky_number_123', + ]); + + $this->assertEquals($this->client->id, $base_transformer->getInvoiceClientId("TRICKY_number_123")); + $this->assertEquals($this->client->id, $base_transformer->getInvoiceClientId(" TRICKY_number_123")); + $this->assertEquals($this->client->id, $base_transformer->getInvoiceClientId(" TRICKY_number_123 ")); + + } + + public function testGetVendorId() + { + $base_transformer = new BaseTransformer($this->company); + + $vendor = Vendor::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'id_number' => 'hit', + 'name' => 'maGic ', + ]); + + + $this->assertEquals($vendor->id, $base_transformer->getVendorId("magic")); + $this->assertEquals($vendor->id, $base_transformer->getVendorId("Magic")); + $this->assertEquals($vendor->id, $base_transformer->getVendorId("Ma gi c ")); + + } + + + // public function testClientCsvImport() // { diff --git a/tests/Feature/Import/CSV/CsvImportTest.php b/tests/Feature/Import/CSV/CsvImportTest.php new file mode 100644 index 000000000000..76c2631bba4b --- /dev/null +++ b/tests/Feature/Import/CSV/CsvImportTest.php @@ -0,0 +1,136 @@ +withoutMiddleware( + ThrottleRequests::class + ); + + config(['database.default' => config('ninja.db.default')]); + + $this->makeTestData(); + + $this->withoutExceptionHandling(); + } + + public function testCsvFeature() + { + $csv = file_get_contents(base_path().'/tests/Feature/Import/clients.csv'); + $hash = Str::random(32); + $column_map = [ + 1 => 'client.balance', + 2 => 'client.paid_to_date', + 0 => 'client.name', + 19 => 'client.currency_id', + 20 => 'client.public_notes', + 21 => 'client.private_notes', + 22 => 'contact.first_name', + 23 => 'contact.last_name', + 24 => 'contact.email', + ]; + + $data = [ + 'hash' => $hash, + 'column_map' => [ 'client' => [ 'mapping' => $column_map ] ], + 'skip_header' => true, + 'import_type' => 'csv', + ]; + + Cache::put( $hash . '-client', base64_encode( $csv ), 360 ); + + $csv_importer = new Csv($data, $this->company); + + $this->assertInstanceOf(Csv::class, $csv_importer); + + $csv_importer->import('client'); + + $base_transformer = new BaseTransformer($this->company); + + $this->assertTrue($base_transformer->hasClient("Ludwig Krajcik DVM")); + + $client_id = $base_transformer->getClient("Ludwig Krajcik DVM", null); + + $c = Client::find($client_id); + + $this->assertEquals($client_id, $c->id); + + $client_id = $base_transformer->getClient("a non existent clent", "brook59@example.org"); + + $this->assertEquals($client_id, $c->id); + + } + +} + + + // public function testClientCsvImport() + // { + // $csv = file_get_contents(base_path().'/tests/Feature/Import/clients.csv'); + // $hash = Str::random(32); + // $column_map = [ + // 1 => 'client.balance', + // 2 => 'client.paid_to_date', + // 0 => 'client.name', + // 19 => 'client.currency_id', + // 20 => 'client.public_notes', + // 21 => 'client.private_notes', + // 22 => 'contact.first_name', + // 23 => 'contact.last_name', + // ]; + + // $data = [ + // 'hash' => $hash, + // 'column_map' => [ 'client' => [ 'mapping' => $column_map ] ], + // 'skip_header' => true, + // 'import_type' => 'csv', + // ]; + + // $pre_import = Client::count(); + + // Cache::put( $hash . '-client', base64_encode( $csv ), 360 ); + + // CSVImport::dispatchNow( $data, $this->company ); + + // $this->assertGreaterThan( $pre_import, Client::count() ); + // }