mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 08:17:32 -05:00 
			
		
		
		
	minor adjustments
This commit is contained in:
		
							parent
							
								
									8f82b27e50
								
							
						
					
					
						commit
						7f226fe5d2
					
				@ -93,6 +93,12 @@ class StoreInvoiceRequest extends Request
 | 
				
			|||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(\Illuminate\Support\Facades\Cache::has($this->ip()."|INVOICE|".$this->input('client_id', '')."|".$user->company()->company_key)) {
 | 
				
			||||||
 | 
					            usleep(200000);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        \Illuminate\Support\Facades\Cache::put($this->ip()."|INVOICE|".$this->input('client_id', '')."|".$user->company()->company_key,1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $input = $this->all();
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $input = $this->decodePrimaryKeys($input);
 | 
					        $input = $this->decodePrimaryKeys($input);
 | 
				
			||||||
 | 
				
			|||||||
@ -154,7 +154,6 @@ class PaymentRepository extends BaseRepository
 | 
				
			|||||||
                if ($invoice) {
 | 
					                if ($invoice) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    //25-06-2023
 | 
					                    //25-06-2023
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    $paymentable = new Paymentable();
 | 
					                    $paymentable = new Paymentable();
 | 
				
			||||||
                    $paymentable->payment_id = $payment->id;
 | 
					                    $paymentable->payment_id = $payment->id;
 | 
				
			||||||
                    $paymentable->paymentable_id = $invoice->id;
 | 
					                    $paymentable->paymentable_id = $invoice->id;
 | 
				
			||||||
 | 
				
			|||||||
@ -13,11 +13,18 @@ namespace App\Services\Import\Quickbooks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use App\Factory\ClientContactFactory;
 | 
					use App\Factory\ClientContactFactory;
 | 
				
			||||||
use App\Factory\ClientFactory;
 | 
					use App\Factory\ClientFactory;
 | 
				
			||||||
 | 
					use App\Factory\InvoiceFactory;
 | 
				
			||||||
 | 
					use App\Factory\ProductFactory;
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use App\Models\Product;
 | 
				
			||||||
use QuickBooksOnline\API\Core\CoreConstants;
 | 
					use QuickBooksOnline\API\Core\CoreConstants;
 | 
				
			||||||
use QuickBooksOnline\API\DataService\DataService;
 | 
					use QuickBooksOnline\API\DataService\DataService;
 | 
				
			||||||
use App\Services\Import\Quickbooks\Transformers\ClientTransformer;
 | 
					use App\Services\Import\Quickbooks\Transformers\ClientTransformer;
 | 
				
			||||||
 | 
					use App\Services\Import\Quickbooks\Transformers\InvoiceTransformer;
 | 
				
			||||||
 | 
					use App\Services\Import\Quickbooks\Transformers\PaymentTransformer;
 | 
				
			||||||
 | 
					use App\Services\Import\Quickbooks\Transformers\ProductTransformer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// quickbooks_realm_id
 | 
					// quickbooks_realm_id
 | 
				
			||||||
// quickbooks_refresh_token
 | 
					// quickbooks_refresh_token
 | 
				
			||||||
@ -27,12 +34,12 @@ class QuickbooksService
 | 
				
			|||||||
    public DataService $sdk;
 | 
					    public DataService $sdk;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    private $entities = [
 | 
					    private $entities = [
 | 
				
			||||||
 | 
					        'product' => 'Item',
 | 
				
			||||||
        'client' => 'Customer',
 | 
					        'client' => 'Customer',
 | 
				
			||||||
        'invoice' => 'Invoice',
 | 
					        'invoice' => 'Invoice',
 | 
				
			||||||
        'quote' => 'Estimate',
 | 
					        'quote' => 'Estimate',
 | 
				
			||||||
        'purchase_order' => 'PurchaseOrder',
 | 
					        'purchase_order' => 'PurchaseOrder',
 | 
				
			||||||
        'payment' => 'Payment',
 | 
					        'payment' => 'Payment',
 | 
				
			||||||
        'product' => 'Item',
 | 
					 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private bool $testMode = true;
 | 
					    private bool $testMode = true;
 | 
				
			||||||
@ -101,7 +108,7 @@ class QuickbooksService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            $records = $this->sdk()->fetchRecords($entity);
 | 
					            $records = $this->sdk()->fetchRecords($entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nlog($records);
 | 
					            nlog(json_encode($records));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $this->processEntitySync($key, $records);
 | 
					            $this->processEntitySync($key, $records);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -126,25 +133,96 @@ class QuickbooksService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function processEntitySync(string $entity, $records)
 | 
					    private function processEntitySync(string $entity, $records)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        nlog($entity);
 | 
					 | 
				
			||||||
        nlog($records);
 | 
					 | 
				
			||||||
        match($entity){
 | 
					        match($entity){
 | 
				
			||||||
            'client' => $this->syncQbToNinjaClients($records),
 | 
					            // 'client' => $this->syncQbToNinjaClients($records),
 | 
				
			||||||
 | 
					            // 'product' => $this->syncQbToNinjaProducts($records),
 | 
				
			||||||
 | 
					            'invoice' => $this->syncQbToNinjaInvoices($records),
 | 
				
			||||||
            // 'vendor' => $this->syncQbToNinjaClients($records),
 | 
					            // 'vendor' => $this->syncQbToNinjaClients($records),
 | 
				
			||||||
            // 'invoice' => $this->syncInvoices($records),
 | 
					 | 
				
			||||||
            // 'quote' => $this->syncInvoices($records),
 | 
					            // 'quote' => $this->syncInvoices($records),
 | 
				
			||||||
            // 'purchase_order' => $this->syncInvoices($records),
 | 
					            // 'purchase_order' => $this->syncInvoices($records),
 | 
				
			||||||
            // 'payment' => $this->syncPayment($records), 
 | 
					            // 'payment' => $this->syncPayment($records), 
 | 
				
			||||||
            // 'product' => $this->syncItem($records),
 | 
					 | 
				
			||||||
            default => false,
 | 
					            default => false,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function syncQbToNinjaClients(array $records)
 | 
					    private function syncQbToNinjaInvoices($records): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        nlog("qb => ninja");
 | 
					        $invoice_transformer = new InvoiceTransformer($this->company);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $client_transformer = new ClientTransformer();
 | 
					        foreach($records as $record)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $ninja_invoice_data = $invoice_transformer->qbToNinja($record);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $payment_ids = $ninja_invoice_data['payment_ids'] ?? [];
 | 
				
			||||||
 | 
					            $client_id = $ninja_invoice_data['client_id'] ?? null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(is_null($client_id))
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            unset($ninja_invoice_data['payment_ids']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($invoice = $this->findInvoice($ninja_invoice_data))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $invoice->fill($ninja_invoice_data);
 | 
				
			||||||
 | 
					                $invoice->saveQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $invoice = $invoice->calc()->getInvoice()->service()->markSent()->save();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					                foreach($payment_ids as $payment_id)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $payment = $this->sdk->FindById('Payment', $payment_id);
 | 
				
			||||||
 | 
					                    $payment_transformer = new PaymentTransformer($this->company);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $transformed = $payment_transformer->qbToNinja($payment);
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    $ninja_payment = $payment_transformer->buildPayment($payment);
 | 
				
			||||||
 | 
					                    $ninja_payment->service()->applyNumber()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $paymentable = new \App\Models\Paymentable();
 | 
				
			||||||
 | 
					                    $paymentable->payment_id = $ninja_payment->id;
 | 
				
			||||||
 | 
					                    $paymentable->paymentable_id = $invoice->id;
 | 
				
			||||||
 | 
					                    $paymentable->paymentable_type = 'invoices';
 | 
				
			||||||
 | 
					                    $paymentable->amount = $transformed['applied'];
 | 
				
			||||||
 | 
					                    $paymentable->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $invoice->service()->applyPayment($ninja_payment, $transformed['applied']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $ninja_invoice_data = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function findInvoice(array $ninja_invoice_data): ?Invoice
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $search = Invoice::query()
 | 
				
			||||||
 | 
					                            ->withTrashed()
 | 
				
			||||||
 | 
					                            ->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
					                            ->where('number', $ninja_invoice_data['number']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($search->count() == 0) {
 | 
				
			||||||
 | 
					            //new invoice
 | 
				
			||||||
 | 
					            $invoice = InvoiceFactory::create($this->company->id, $this->company->owner()->id);
 | 
				
			||||||
 | 
					            $invoice->client_id = $ninja_invoice_data['client_id'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $invoice;
 | 
				
			||||||
 | 
					        } elseif($search->count() == 1) {
 | 
				
			||||||
 | 
					            return $this->settings['invoice']['update_record'] ? $search->first() : null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function syncQbToNinjaClients(array $records): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $client_transformer = new ClientTransformer($this->company);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach($records as $record)
 | 
					        foreach($records as $record)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -176,14 +254,28 @@ class QuickbooksService
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function syncQbToNinjaProducts($records): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $product_transformer = new ProductTransformer($this->company);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach($records as $record)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $ninja_data = $product_transformer->qbToNinja($record);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($product = $this->findProduct($ninja_data['product_key']))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $product->fill($ninja_data);
 | 
				
			||||||
 | 
					                $product->save();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function findClient(array $qb_data) :?Client
 | 
					    private function findClient(array $qb_data) :?Client
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $client = $qb_data[0];
 | 
					        $client = $qb_data[0];
 | 
				
			||||||
        $contact = $qb_data[1];
 | 
					        $contact = $qb_data[1];
 | 
				
			||||||
        $client_meta = $qb_data[2];
 | 
					        $client_meta = $qb_data[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        nlog($qb_data);
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        $search = Client::query()
 | 
					        $search = Client::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->where('company_id', $this->company->id)
 | 
					                        ->where('company_id', $this->company->id)
 | 
				
			||||||
@ -208,8 +300,28 @@ class QuickbooksService
 | 
				
			|||||||
        elseif($search->count() == 1) {
 | 
					        elseif($search->count() == 1) {
 | 
				
			||||||
            return $this->settings['client']['update_record'] ? $search->first() : null;
 | 
					            return $this->settings['client']['update_record'] ? $search->first() : null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        
 | 
				
			||||||
            //potentially multiple matching clients?
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function findProduct(string $key): ?Product
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $search = Product::query()
 | 
				
			||||||
 | 
					                         ->withTrashed()
 | 
				
			||||||
 | 
					                         ->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
					                         ->where('product_key', $key);
 | 
				
			||||||
 | 
					             
 | 
				
			||||||
 | 
					        if($search->count() == 0) {
 | 
				
			||||||
 | 
					            //new product
 | 
				
			||||||
 | 
					            $product = ProductFactory::create($this->company->id, $this->company->owner()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $product;
 | 
				
			||||||
 | 
					        } elseif($search->count() == 1) {
 | 
				
			||||||
 | 
					            return $this->settings['product']['update_record'] ? $search->first() : null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ class SdkWrapper
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public const MAXRESULTS = 10000;
 | 
					    public const MAXRESULTS = 10000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private $entities = ['Customer','Invoice','Payment','Item'];
 | 
					    private $entities = ['Customer','Invoice','Item'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private OAuth2AccessToken $token;
 | 
					    private OAuth2AccessToken $token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -198,6 +198,7 @@ class SdkWrapper
 | 
				
			|||||||
            nlog("Fetch Quickbooks API Error: {$th->getMessage()}");
 | 
					            nlog("Fetch Quickbooks API Error: {$th->getMessage()}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nlog($records);
 | 
				
			||||||
        return $records;
 | 
					        return $records;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://clientninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Services\Import\Quickbooks\Transformers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class BaseTransformer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class BaseTransformer
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(public Company $company)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function resolveCountry(string $iso_3_code): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var \App\Models\Country $country */
 | 
				
			||||||
 | 
					        $country = app('countries')->first(function ($c) use ($iso_3_code){
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            /** @var \App\Models\Country $c */
 | 
				
			||||||
 | 
					            return $c->iso_3166_3 == $iso_3_code;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return $country ? (string) $country->id : '840';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function resolveCurrency(string $currency_code): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /** @var \App\Models\Currency $currency */
 | 
				
			||||||
 | 
					        $currency = app('currencies')->first(function($c) use ($currency_code){
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            /** @var \App\Models\Currency $c */
 | 
				
			||||||
 | 
					            return $c->code == $currency_code;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return $currency ? (string) $currency->id : '1';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getShipAddrCountry($data, $field)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return is_null(($c = $this->getString($data, $field))) ? null : $this->getCountryId($c);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getBillAddrCountry($data, $field)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return is_null(($c = $this->getString($data, $field))) ? null : $this->getCountryId($c);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getClientId($customer_reference_id): ?int
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $client = Client::query()
 | 
				
			||||||
 | 
					                    ->withTrashed()
 | 
				
			||||||
 | 
					                    ->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
					                    ->where('id_number', $customer_reference_id)
 | 
				
			||||||
 | 
					                    ->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $client ? $client->id : null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -17,13 +17,9 @@ use App\DataMapper\ClientSettings;
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class ClientTransformer.
 | 
					 * Class ClientTransformer.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class ClientTransformer
 | 
					class ClientTransformer extends BaseTransformer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function qbToNinja(mixed $qb_data)
 | 
					    public function qbToNinja(mixed $qb_data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->transform($qb_data);
 | 
					        return $this->transform($qb_data);
 | 
				
			||||||
@ -31,7 +27,6 @@ class ClientTransformer
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function ninjaToQb()
 | 
					    public function ninjaToQb()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function transform(mixed $data): array
 | 
					    public function transform(mixed $data): array
 | 
				
			||||||
@ -72,32 +67,4 @@ class ClientTransformer
 | 
				
			|||||||
        return [$client, $contact, $new_client_merge];
 | 
					        return [$client, $contact, $new_client_merge];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function resolveCountry(string $iso_3_code)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $country = app('countries')->first(function ($c) use ($iso_3_code){
 | 
					 | 
				
			||||||
            return $c->iso_3166_3 == $iso_3_code;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return $country ? (string) $country->id : '840';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private function resolveCurrency(string $currency_code)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $currency = app('currencies')->first(function($c) use ($currency_code){
 | 
					 | 
				
			||||||
            return $c->code == $currency_code;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return $currency ? (string) $currency->id : '1';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getShipAddrCountry($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return is_null(($c = $this->getString($data, $field))) ? null : $this->getCountryId($c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getBillAddrCountry($data, $field)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return is_null(($c = $this->getString($data, $field))) ? null : $this->getCountryId($c);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 * Invoice Ninja (https://clientninja.com).
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -9,192 +10,247 @@
 | 
				
			|||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Import\Transformer\Quickbooks;
 | 
					namespace App\Services\Import\Quickbooks\Transformers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use Illuminate\Support\Arr;
 | 
					use App\Models\Product;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					 | 
				
			||||||
use App\DataMapper\InvoiceItem;
 | 
					use App\DataMapper\InvoiceItem;
 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use App\Models\Invoice as Model;
 | 
					 | 
				
			||||||
use App\Import\Transformer\BaseTransformer;
 | 
					 | 
				
			||||||
use App\Import\Transformer\Quickbooks\CommonTrait;
 | 
					 | 
				
			||||||
use App\Import\Transformer\Quickbooks\ClientTransformer;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class InvoiceTransformer.
 | 
					 * Class InvoiceTransformer.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class InvoiceTransformer extends BaseTransformer
 | 
					class InvoiceTransformer extends BaseTransformer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use CommonTrait {
 | 
					 | 
				
			||||||
        transform as preTransform;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private $fillable = [
 | 
					    public function qbToNinja(mixed $qb_data)
 | 
				
			||||||
        'amount' => "TotalAmt",
 | 
					 | 
				
			||||||
        'line_items' => "Line",
 | 
					 | 
				
			||||||
        'due_date' => "DueDate",
 | 
					 | 
				
			||||||
        'partial' => "Deposit",
 | 
					 | 
				
			||||||
        'balance' => "Balance",
 | 
					 | 
				
			||||||
        'private_notes' => "CustomerMemo",
 | 
					 | 
				
			||||||
        'public_notes' => "CustomerMemo",
 | 
					 | 
				
			||||||
        'number' => "DocNumber",
 | 
					 | 
				
			||||||
        'created_at' => "CreateTime",
 | 
					 | 
				
			||||||
        'updated_at' => "LastUpdatedTime",
 | 
					 | 
				
			||||||
        'payments' => 'LinkedTxn',
 | 
					 | 
				
			||||||
        'status_id' => 'InvoiceStatus',
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function __construct($company)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::__construct($company);
 | 
					        return $this->transform($qb_data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->model = new Model();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getInvoiceStatus($data)
 | 
					    public function ninjaToQb()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return Invoice::STATUS_SENT;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function transform($data)
 | 
					    public function transform($qb_data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->preTransform($data) + $this->getInvoiceClient($data);
 | 
					        $client_id = $this->getClientId(data_get($qb_data, 'CustomerRef.value', null));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $client_id ? [
 | 
				
			||||||
 | 
					            'client_id' => $client_id,
 | 
				
			||||||
 | 
					            'number' => data_get($qb_data, 'DocNumber', false),
 | 
				
			||||||
 | 
					            'date' => data_get($qb_data, 'TxnDate', now()->format('Y-m-d')),
 | 
				
			||||||
 | 
					            'private_notes' => data_get($qb_data, 'PrivateNote', ''),
 | 
				
			||||||
 | 
					            'public_notes' => data_get($qb_data, 'CustomerMemo.value', false),
 | 
				
			||||||
 | 
					            'due_date' => data_get($qb_data, 'DueDate', null),
 | 
				
			||||||
 | 
					            'po_number' => data_get($qb_data, 'PONumber', ""),
 | 
				
			||||||
 | 
					            'partial' => data_get($qb_data, 'Deposit', 0),
 | 
				
			||||||
 | 
					            'line_items' => $this->getLineItems(data_get($qb_data, 'Line', [])),
 | 
				
			||||||
 | 
					            'payment_ids' => $this->getPayments($qb_data),
 | 
				
			||||||
 | 
					            'status_id' => Invoice::STATUS_SENT,
 | 
				
			||||||
 | 
					            'tax_rate1' => $rate = data_get($qb_data,'TxnTaxDetail.TaxLine.TaxLineDetail.TaxPercent', 0),
 | 
				
			||||||
 | 
					            'tax_name1' => $rate > 0 ? "Sales Tax" : "",
 | 
				
			||||||
 | 
					        ] : false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getTotalAmt($data)
 | 
					    private function getPayments(mixed $qb_data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return (float) $this->getString($data, 'TotalAmt');
 | 
					        $payments = [];
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getLine($data)
 | 
					        nlog("get payments");
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return array_map(function ($item) {
 | 
					 | 
				
			||||||
            return [
 | 
					 | 
				
			||||||
                'description' => $this->getString($item, 'Description'),
 | 
					 | 
				
			||||||
                'product_key' => $this->getString($item, 'Description'),
 | 
					 | 
				
			||||||
                'quantity' => (int) $this->getString($item, 'SalesItemLineDetail.Qty'),
 | 
					 | 
				
			||||||
                'unit_price' => (float) $this->getString($item, 'SalesItemLineDetail.UnitPrice'),
 | 
					 | 
				
			||||||
                'line_total' => (float) $this->getString($item, 'Amount'),
 | 
					 | 
				
			||||||
                'cost' => (float) $this->getString($item, 'SalesItemLineDetail.UnitPrice'),
 | 
					 | 
				
			||||||
                'product_cost' => (float) $this->getString($item, 'SalesItemLineDetail.UnitPrice'),
 | 
					 | 
				
			||||||
                'tax_amount' => (float) $this->getString($item, 'TxnTaxDetail.TotalTax'),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }, array_filter($this->getString($data, 'Line'), function ($item) {
 | 
					 | 
				
			||||||
            return $this->getString($item, 'DetailType') !== 'SubTotalLineDetail';
 | 
					 | 
				
			||||||
        }));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getInvoiceClient($data, $field = null)
 | 
					        $qb_payments = data_get($qb_data, 'LinkedTxn', false);
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /**
 | 
					 | 
				
			||||||
         *  "CustomerRef": {
 | 
					 | 
				
			||||||
                "value": "23",
 | 
					 | 
				
			||||||
                "name": ""Barnett Design
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "CustomerMemo": {
 | 
					 | 
				
			||||||
                "value": "Thank you for your business and have a great day!"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "BillAddr": {
 | 
					 | 
				
			||||||
                "Id": "58",
 | 
					 | 
				
			||||||
                "Line1": "Shara Barnett",
 | 
					 | 
				
			||||||
                "Line2": "Barnett Design",
 | 
					 | 
				
			||||||
                "Line3": "19 Main St.",
 | 
					 | 
				
			||||||
                "Line4": "Middlefield, CA  94303",
 | 
					 | 
				
			||||||
                "Lat": "37.4530553",
 | 
					 | 
				
			||||||
                "Long": "-122.1178261"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "ShipAddr": {
 | 
					 | 
				
			||||||
                "Id": "24",
 | 
					 | 
				
			||||||
                "Line1": "19 Main St.",
 | 
					 | 
				
			||||||
                "City": "Middlefield",
 | 
					 | 
				
			||||||
                "CountrySubDivisionCode": "CA",
 | 
					 | 
				
			||||||
                "PostalCode": "94303",
 | 
					 | 
				
			||||||
                "Lat": "37.445013",
 | 
					 | 
				
			||||||
                "Long": "-122.1391443"
 | 
					 | 
				
			||||||
                },"BillEmail": {
 | 
					 | 
				
			||||||
                "Address": "Design@intuit.com"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                    [
 | 
					 | 
				
			||||||
                    'name'              => 'CompanyName',
 | 
					 | 
				
			||||||
                    'phone'             => 'PrimaryPhone.FreeFormNumber',
 | 
					 | 
				
			||||||
                    'country_id'        => 'BillAddr.Country',
 | 
					 | 
				
			||||||
                    'state'             => 'BillAddr.CountrySubDivisionCode',
 | 
					 | 
				
			||||||
                    'address1'          => 'BillAddr.Line1',
 | 
					 | 
				
			||||||
                    'city'              => 'BillAddr.City',
 | 
					 | 
				
			||||||
                    'postal_code'       => 'BillAddr.PostalCode',
 | 
					 | 
				
			||||||
                    'shipping_country_id' => 'ShipAddr.Country',
 | 
					 | 
				
			||||||
                    'shipping_state'    => 'ShipAddr.CountrySubDivisionCode',
 | 
					 | 
				
			||||||
                    'shipping_address1' => 'ShipAddr.Line1',
 | 
					 | 
				
			||||||
                    'shipping_city'     => 'ShipAddr.City',
 | 
					 | 
				
			||||||
                    'shipping_postal_code' => 'ShipAddr.PostalCode',
 | 
					 | 
				
			||||||
                    'public_notes'      => 'Notes'
 | 
					 | 
				
			||||||
                ];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
         */
 | 
					        nlog($qb_payments);
 | 
				
			||||||
        $bill_address = (object) $this->getString($data, 'BillAddr');
 | 
					 | 
				
			||||||
        $ship_address = $this->getString($data, 'ShipAddr');
 | 
					 | 
				
			||||||
        $customer = explode(" ", $this->getString($data, 'CustomerRef.name'));
 | 
					 | 
				
			||||||
        $customer = ['GivenName' => $customer[0], 'FamilyName' => $customer[1]];
 | 
					 | 
				
			||||||
        $has_company = property_exists($bill_address, 'Line4');
 | 
					 | 
				
			||||||
        $address = $has_company ? $bill_address->Line4 : $bill_address->Line3;
 | 
					 | 
				
			||||||
        $address_1 = substr($address, 0, stripos($address, ','));
 | 
					 | 
				
			||||||
        $address = array_filter([$address_1] + (explode(' ', substr($address, stripos($address, ",") + 1))));
 | 
					 | 
				
			||||||
        $client_id = null;
 | 
					 | 
				
			||||||
        $client =
 | 
					 | 
				
			||||||
        [
 | 
					 | 
				
			||||||
            "CompanyName" => $has_company ? $bill_address->Line2 : $bill_address->Line1,
 | 
					 | 
				
			||||||
            "BillAddr" => array_combine(['City','CountrySubDivisionCode','PostalCode'], array_pad($address, 3, 'N/A')) + ['Line1' => $has_company ? $bill_address->Line3 : $bill_address->Line2 ],
 | 
					 | 
				
			||||||
            "ShipAddr" => $ship_address
 | 
					 | 
				
			||||||
        ] + $customer + ['PrimaryEmailAddr' => ['Address' => $this->getString($data, 'BillEmail.Address') ]];
 | 
					 | 
				
			||||||
        if($this->hasClient($client['CompanyName'])) {
 | 
					 | 
				
			||||||
            $client_id = $this->getClient($client['CompanyName'], $this->getString($client, 'PrimaryEmailAddr.Address'));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!$qb_payments) {
 | 
				
			||||||
        return ['client' => (new ClientTransformer($this->company))->transform($client), 'client_id' => $client_id ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getDueDate($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->parseDateOrNull($data, 'DueDate');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getDeposit($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (float) $this->getString($data, 'Deposit');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getBalance($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (float) $this->getString($data, 'Balance');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getCustomerMemo($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->getString($data, 'CustomerMemo.value');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getDocNumber($data, $field = null)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return sprintf(
 | 
					 | 
				
			||||||
            "%s-%s",
 | 
					 | 
				
			||||||
            $this->getString($data, 'DocNumber'),
 | 
					 | 
				
			||||||
            $this->getString($data, 'Id.value')
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getLinkedTxn($data)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $payments = $this->getString($data, 'LinkedTxn');
 | 
					 | 
				
			||||||
        if(empty($payments)) {
 | 
					 | 
				
			||||||
            return [];
 | 
					            return [];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return [[
 | 
					        if(!is_array($qb_payments) && data_get($qb_payments, 'TxnType', false) == 'Payment'){
 | 
				
			||||||
             'amount' => $this->getTotalAmt($data),
 | 
					            nlog([data_get($qb_payments, 'TxnId.value', false)]);
 | 
				
			||||||
             'date' => $this->parseDateOrNull($data, 'TxnDate')
 | 
					            return [data_get($qb_payments, 'TxnId.value', false)];
 | 
				
			||||||
         ]];
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        foreach($qb_payments as $payment)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(data_get($payment, 'TxnType', false) == 'Payment')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $payments[] = data_get($payment, 'TxnId.value', false);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $payments;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function getLineItems(mixed $qb_items)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $items = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach($qb_items as $qb_item)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $item = new InvoiceItem;
 | 
				
			||||||
 | 
					            $item->product_key = data_get($qb_item, 'SalesItemLineDetail.ItemRef.name', '');
 | 
				
			||||||
 | 
					            $item->notes = data_get($qb_item,'Description', '');
 | 
				
			||||||
 | 
					            $item->quantity = data_get($qb_item,'SalesItemLineDetail.Qty', 0);
 | 
				
			||||||
 | 
					            $item->cost = data_get($qb_item, 'SalesItemLineDetail.UnitPrice', 0);
 | 
				
			||||||
 | 
					            $item->discount = data_get($item,'DiscountRate', data_get($qb_item,'DiscountAmount', 0));
 | 
				
			||||||
 | 
					            $item->is_amount_discount = data_get($qb_item,'DiscountAmount', 0) > 0 ? true : false;
 | 
				
			||||||
 | 
					            $item->type_id = stripos(data_get($qb_item, 'ItemAccountRef.name'), 'Service') !== false ? '2' : '1';
 | 
				
			||||||
 | 
					            $item->tax_id = data_get($qb_item, 'TaxCodeRef.value', '') == 'NON' ? Product::PRODUCT_TYPE_EXEMPT : $item->type_id;
 | 
				
			||||||
 | 
					            $item->tax_rate1 = data_get($qb_item,'TaxLineDetail.TaxRateRef.TaxPercent', 0);
 | 
				
			||||||
 | 
					            $item->tax_name1 = $item->tax_rate1 > 0 ? "Sales Tax" : "";
 | 
				
			||||||
 | 
					            $items[] = (object)$item;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nlog($items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getTotalAmt($data)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     return (float) $this->getString($data, 'TotalAmt');
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getLine($data)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     return array_map(function ($item) {
 | 
				
			||||||
 | 
					    //         return [
 | 
				
			||||||
 | 
					    //             'description' => $this->getString($item, 'Description'),
 | 
				
			||||||
 | 
					    //             'product_key' => $this->getString($item, 'Description'),
 | 
				
			||||||
 | 
					    //             'quantity' => (int) $this->getString($item, 'SalesItemLineDetail.Qty'),
 | 
				
			||||||
 | 
					    //             'unit_price' => (float) $this->getString($item, 'SalesItemLineDetail.UnitPrice'),
 | 
				
			||||||
 | 
					    //             'line_total' => (float) $this->getString($item, 'Amount'),
 | 
				
			||||||
 | 
					    //             'cost' => (float) $this->getString($item, 'SalesItemLineDetail.UnitPrice'),
 | 
				
			||||||
 | 
					    //             'product_cost' => (float) $this->getString($item, 'SalesItemLineDetail.UnitPrice'),
 | 
				
			||||||
 | 
					    //             'tax_amount' => (float) $this->getString($item, 'TxnTaxDetail.TotalTax'),
 | 
				
			||||||
 | 
					    //         ];
 | 
				
			||||||
 | 
					    //     }, array_filter($this->getString($data, 'Line'), function ($item) {
 | 
				
			||||||
 | 
					    //         return $this->getString($item, 'DetailType') !== 'SubTotalLineDetail';
 | 
				
			||||||
 | 
					    //     }));
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getInvoiceClient($data, $field = null)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     /**
 | 
				
			||||||
 | 
					    //      *  "CustomerRef": {
 | 
				
			||||||
 | 
					    //             "value": "23",
 | 
				
			||||||
 | 
					    //             "name": ""Barnett Design
 | 
				
			||||||
 | 
					    //             },
 | 
				
			||||||
 | 
					    //             "CustomerMemo": {
 | 
				
			||||||
 | 
					    //             "value": "Thank you for your business and have a great day!"
 | 
				
			||||||
 | 
					    //             },
 | 
				
			||||||
 | 
					    //             "BillAddr": {
 | 
				
			||||||
 | 
					    //             "Id": "58",
 | 
				
			||||||
 | 
					    //             "Line1": "Shara Barnett",
 | 
				
			||||||
 | 
					    //             "Line2": "Barnett Design",
 | 
				
			||||||
 | 
					    //             "Line3": "19 Main St.",
 | 
				
			||||||
 | 
					    //             "Line4": "Middlefield, CA  94303",
 | 
				
			||||||
 | 
					    //             "Lat": "37.4530553",
 | 
				
			||||||
 | 
					    //             "Long": "-122.1178261"
 | 
				
			||||||
 | 
					    //             },
 | 
				
			||||||
 | 
					    //             "ShipAddr": {
 | 
				
			||||||
 | 
					    //             "Id": "24",
 | 
				
			||||||
 | 
					    //             "Line1": "19 Main St.",
 | 
				
			||||||
 | 
					    //             "City": "Middlefield",
 | 
				
			||||||
 | 
					    //             "CountrySubDivisionCode": "CA",
 | 
				
			||||||
 | 
					    //             "PostalCode": "94303",
 | 
				
			||||||
 | 
					    //             "Lat": "37.445013",
 | 
				
			||||||
 | 
					    //             "Long": "-122.1391443"
 | 
				
			||||||
 | 
					    //             },"BillEmail": {
 | 
				
			||||||
 | 
					    //             "Address": "Design@intuit.com"
 | 
				
			||||||
 | 
					    //             },
 | 
				
			||||||
 | 
					    //                 [
 | 
				
			||||||
 | 
					    //                 'name'              => 'CompanyName',
 | 
				
			||||||
 | 
					    //                 'phone'             => 'PrimaryPhone.FreeFormNumber',
 | 
				
			||||||
 | 
					    //                 'country_id'        => 'BillAddr.Country',
 | 
				
			||||||
 | 
					    //                 'state'             => 'BillAddr.CountrySubDivisionCode',
 | 
				
			||||||
 | 
					    //                 'address1'          => 'BillAddr.Line1',
 | 
				
			||||||
 | 
					    //                 'city'              => 'BillAddr.City',
 | 
				
			||||||
 | 
					    //                 'postal_code'       => 'BillAddr.PostalCode',
 | 
				
			||||||
 | 
					    //                 'shipping_country_id' => 'ShipAddr.Country',
 | 
				
			||||||
 | 
					    //                 'shipping_state'    => 'ShipAddr.CountrySubDivisionCode',
 | 
				
			||||||
 | 
					    //                 'shipping_address1' => 'ShipAddr.Line1',
 | 
				
			||||||
 | 
					    //                 'shipping_city'     => 'ShipAddr.City',
 | 
				
			||||||
 | 
					    //                 'shipping_postal_code' => 'ShipAddr.PostalCode',
 | 
				
			||||||
 | 
					    //                 'public_notes'      => 'Notes'
 | 
				
			||||||
 | 
					    //             ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //      */
 | 
				
			||||||
 | 
					    //     $bill_address = (object) $this->getString($data, 'BillAddr');
 | 
				
			||||||
 | 
					    //     $ship_address = $this->getString($data, 'ShipAddr');
 | 
				
			||||||
 | 
					    //     $customer = explode(" ", $this->getString($data, 'CustomerRef.name'));
 | 
				
			||||||
 | 
					    //     $customer = ['GivenName' => $customer[0], 'FamilyName' => $customer[1]];
 | 
				
			||||||
 | 
					    //     $has_company = property_exists($bill_address, 'Line4');
 | 
				
			||||||
 | 
					    //     $address = $has_company ? $bill_address->Line4 : $bill_address->Line3;
 | 
				
			||||||
 | 
					    //     $address_1 = substr($address, 0, stripos($address, ','));
 | 
				
			||||||
 | 
					    //     $address = array_filter([$address_1] + (explode(' ', substr($address, stripos($address, ",") + 1))));
 | 
				
			||||||
 | 
					    //     $client_id = null;
 | 
				
			||||||
 | 
					    //     $client =
 | 
				
			||||||
 | 
					    //     [
 | 
				
			||||||
 | 
					    //         "CompanyName" => $has_company ? $bill_address->Line2 : $bill_address->Line1,
 | 
				
			||||||
 | 
					    //         "BillAddr" => array_combine(['City','CountrySubDivisionCode','PostalCode'], array_pad($address, 3, 'N/A')) + ['Line1' => $has_company ? $bill_address->Line3 : $bill_address->Line2 ],
 | 
				
			||||||
 | 
					    //         "ShipAddr" => $ship_address
 | 
				
			||||||
 | 
					    //     ] + $customer + ['PrimaryEmailAddr' => ['Address' => $this->getString($data, 'BillEmail.Address') ]];
 | 
				
			||||||
 | 
					    //     if($this->hasClient($client['CompanyName'])) {
 | 
				
			||||||
 | 
					    //         $client_id = $this->getClient($client['CompanyName'], $this->getString($client, 'PrimaryEmailAddr.Address'));
 | 
				
			||||||
 | 
					    //     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     return ['client' => (new ClientTransformer($this->company))->transform($client), 'client_id' => $client_id ];
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getDueDate($data)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     return $this->parseDateOrNull($data, 'DueDate');
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getDeposit($data)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     return (float) $this->getString($data, 'Deposit');
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getBalance($data)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     return (float) $this->getString($data, 'Balance');
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getCustomerMemo($data)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     return $this->getString($data, 'CustomerMemo.value');
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getDocNumber($data, $field = null)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     return sprintf(
 | 
				
			||||||
 | 
					    //         "%s-%s",
 | 
				
			||||||
 | 
					    //         $this->getString($data, 'DocNumber'),
 | 
				
			||||||
 | 
					    //         $this->getString($data, 'Id.value')
 | 
				
			||||||
 | 
					    //     );
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function getLinkedTxn($data)
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     $payments = $this->getString($data, 'LinkedTxn');
 | 
				
			||||||
 | 
					    //     if(empty($payments)) {
 | 
				
			||||||
 | 
					    //         return [];
 | 
				
			||||||
 | 
					    //     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     return [[
 | 
				
			||||||
 | 
					    //          'amount' => $this->getTotalAmt($data),
 | 
				
			||||||
 | 
					    //          'date' => $this->parseDateOrNull($data, 'TxnDate')
 | 
				
			||||||
 | 
					    //      ]];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Invoice Ninja (https://Paymentninja.com).
 | 
					 * Invoice Ninja (https://Paymentninja.com).
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -10,15 +9,11 @@
 | 
				
			|||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Import\Transformer\Quickbooks;
 | 
					namespace App\Services\Import\Quickbooks\Transformers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Import\Transformer\Quickbooks\CommonTrait;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Import\Transformer\BaseTransformer;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Models\Payment as Model;
 | 
					use App\Factory\PaymentFactory;
 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					 | 
				
			||||||
use Illuminate\Support\Arr;
 | 
					 | 
				
			||||||
use App\Models\Invoice;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -26,45 +21,48 @@ use App\Models\Invoice;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
class PaymentTransformer extends BaseTransformer
 | 
					class PaymentTransformer extends BaseTransformer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use CommonTrait;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $fillable = [
 | 
					    public function qbToNinja(mixed $qb_data)
 | 
				
			||||||
        'number' => "PaymentRefNum",
 | 
					    {
 | 
				
			||||||
        'amount' => "TotalAmt",
 | 
					        return $this->transform($qb_data);
 | 
				
			||||||
        "client_id" => "CustomerRef",
 | 
					    }
 | 
				
			||||||
        "currency_id" => "CurrencyRef",
 | 
					
 | 
				
			||||||
        'date' => "TxnDate",
 | 
					    public function ninjaToQb()
 | 
				
			||||||
        "invoices" => "Line",
 | 
					    {
 | 
				
			||||||
        'private_notes' => "PrivateNote",
 | 
					    }
 | 
				
			||||||
        'created_at' => "CreateTime",
 | 
					
 | 
				
			||||||
        'updated_at' => "LastUpdatedTime"
 | 
					    public function transform(mixed $qb_data)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'date' => data_get($qb_data, 'TxnDate', now()->format('Y-m-d')),  
 | 
				
			||||||
 | 
					            'amount' => floatval(data_get($qb_data, 'TotalAmt', 0)), 
 | 
				
			||||||
 | 
					            'applied' => data_get($qb_data, 'TotalAmt', 0) - data_get($qb_data, 'UnappliedAmt', 0), 
 | 
				
			||||||
 | 
					            'number' => data_get($qb_data, 'DocNumber', null),
 | 
				
			||||||
 | 
					            'private_notes' => data_get($qb_data, 'PrivateNote', null),
 | 
				
			||||||
 | 
					            'currency_id' => (string) $this->resolveCurrency(data_get($qb_data, 'CurrencyRef.value')),
 | 
				
			||||||
 | 
					            'client_id' => $this->getClientId(data_get($qb_data, 'CustomerRef.value', null)),    
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function __construct($company)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::__construct($company);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->model = new Model();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    public function getTotalAmt($data, $field = null)
 | 
					    public function buildPayment($qb_data): ?Payment
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return (float) $this->getString($data, $field);
 | 
					        $ninja_payment_data = $this->transform($qb_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($ninja_payment_data['client_id'])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $payment = PaymentFactory::create($this->company->id, $this->company->owner()->id,$ninja_payment_data['client_id']);
 | 
				
			||||||
 | 
					            $payment->amount = $ninja_payment_data['amount'];
 | 
				
			||||||
 | 
					            $payment->applied = $ninja_payment_data['applied'];
 | 
				
			||||||
 | 
					            $payment->status_id = 4;
 | 
				
			||||||
 | 
					            $payment->fill($ninja_payment_data);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $payment->client->service()->updatePaidToDate($payment->amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $payment;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getTxnDate($data, $field = null)
 | 
					        return null;
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->parseDateOrNull($data, $field);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getCustomerRef($data, $field = null)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->getClient($this->getString($data, 'CustomerRef.name'), null);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getCurrencyRef($data, $field = null)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->getCurrencyByCode($data['CurrencyRef'], 'value');
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getLine($data, $field = null)
 | 
					    public function getLine($data, $field = null)
 | 
				
			||||||
@ -84,23 +82,4 @@ class PaymentTransformer extends BaseTransformer
 | 
				
			|||||||
        ]];
 | 
					        ]];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
    * @param $invoice_number
 | 
					 | 
				
			||||||
    *
 | 
					 | 
				
			||||||
    * @return int|null
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
    public function getInvoiceId($invoice_number)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invoice = Invoice::query()->where('company_id', $this->company->id)
 | 
					 | 
				
			||||||
            ->where('is_deleted', false)
 | 
					 | 
				
			||||||
            ->where(
 | 
					 | 
				
			||||||
                "number",
 | 
					 | 
				
			||||||
                "LIKE",
 | 
					 | 
				
			||||||
                "%-$invoice_number%",
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            ->first();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $invoice ? $invoice->id : null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Invoice Ninja (https://Productninja.com).
 | 
					 * Invoice Ninja (https://clientninja.com).
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -10,52 +10,35 @@
 | 
				
			|||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Import\Transformer\Quickbooks;
 | 
					namespace App\Services\Import\Quickbooks\Transformers;
 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Import\Transformer\Quickbooks\CommonTrait;
 | 
					 | 
				
			||||||
use App\Import\Transformer\BaseTransformer;
 | 
					 | 
				
			||||||
use App\Models\Product as Model;
 | 
					 | 
				
			||||||
use App\Import\ImportException;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class ProductTransformer.
 | 
					 * Class ProductTransformer.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class ProductTransformer extends BaseTransformer
 | 
					class ProductTransformer extends BaseTransformer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use CommonTrait;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $fillable = [
 | 
					    public function qbToNinja(mixed $qb_data)
 | 
				
			||||||
        'product_key' => 'Name',
 | 
					    {
 | 
				
			||||||
        'notes' => 'Description',
 | 
					        return $this->transform($qb_data);
 | 
				
			||||||
        'cost' => 'PurchaseCost',
 | 
					    }
 | 
				
			||||||
        'price' => 'UnitPrice',
 | 
					
 | 
				
			||||||
        'quantity' => 'QtyOnHand',
 | 
					    public function ninjaToQb()
 | 
				
			||||||
        'in_stock_quantity' => 'QtyOnHand',
 | 
					    {
 | 
				
			||||||
        'created_at' => 'CreateTime',
 | 
					
 | 
				
			||||||
        'updated_at' => 'LastUpdatedTime',
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function transform(mixed $data): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'product_key' => data_get($data, 'Name', data_get($data, 'FullyQualifiedName','')),
 | 
				
			||||||
 | 
					            'notes' => data_get($data, 'Description', ''),
 | 
				
			||||||
 | 
					            'cost' => data_get($data, 'PurchaseCost', 0),
 | 
				
			||||||
 | 
					            'price' => data_get($data, 'UnitPrice', 0),
 | 
				
			||||||
 | 
					            'in_stock_quantity' => data_get($data, 'QtyOnHand', 0),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function __construct($company)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::__construct($company);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->model = new Model();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getQtyOnHand($data, $field = null)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (int) $this->getString($data, $field);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getPurchaseCost($data, $field = null)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (float) $this->getString($data, $field);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function getUnitPrice($data, $field = null)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return (float) $this->getString($data, $field);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -109,6 +109,8 @@ class InvoiceService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Apply a payment amount to an invoice.
 | 
					     * Apply a payment amount to an invoice.
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * *** does not create a paymentable ****
 | 
				
			||||||
     * @param  Payment $payment        The Payment
 | 
					     * @param  Payment $payment        The Payment
 | 
				
			||||||
     * @param  float   $payment_amount The Payment amount
 | 
					     * @param  float   $payment_amount The Payment amount
 | 
				
			||||||
     * @return InvoiceService          Parent class object
 | 
					     * @return InvoiceService          Parent class object
 | 
				
			||||||
 | 
				
			|||||||
@ -103,7 +103,6 @@ class MarkPaid extends AbstractService
 | 
				
			|||||||
        $this->invoice
 | 
					        $this->invoice
 | 
				
			||||||
                ->service()
 | 
					                ->service()
 | 
				
			||||||
                ->applyNumber()
 | 
					                ->applyNumber()
 | 
				
			||||||
                // ->deletePdf()
 | 
					 | 
				
			||||||
                ->save();
 | 
					                ->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $payment->ledger()
 | 
					        $payment->ledger()
 | 
				
			||||||
 | 
				
			|||||||
@ -31,109 +31,10 @@ class QuickbooksTest extends TestCase
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::setUp();
 | 
					        parent::setUp();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $this->markTestSkipped("NO BUENO");
 | 
					 | 
				
			||||||
        $this->withoutMiddleware(ThrottleRequests::class);
 | 
					 | 
				
			||||||
        config(['database.default' => config('ninja.db.default')]);
 | 
					 | 
				
			||||||
        $this->makeTestData();
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        $this->withoutExceptionHandling();
 | 
					 | 
				
			||||||
        Auth::setUser($this->user);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testImportCallsGetDataOnceForClient()
 | 
					    public function testCustomerSync()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $data = (json_decode(file_get_contents(base_path('tests/Feature/Import/customers.json')), true))['Customer'];
 | 
					        $data = (json_decode(file_get_contents(base_path('tests/Feature/Import/Quickbooks/customers.json')), false));
 | 
				
			||||||
        $hash = Str::random(32);
 | 
					 | 
				
			||||||
        Cache::put($hash.'-client', base64_encode(json_encode($data)), 360);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $quickbooks = Mockery::mock(Quickbooks::class, [[
 | 
					 | 
				
			||||||
            'hash' => $hash,
 | 
					 | 
				
			||||||
            'column_map' => ['client' => ['mapping' => []]],
 | 
					 | 
				
			||||||
            'skip_header' => true,
 | 
					 | 
				
			||||||
            'import_type' => 'quickbooks',
 | 
					 | 
				
			||||||
        ], $this->company ])->makePartial();
 | 
					 | 
				
			||||||
        $quickbooks->shouldReceive('getData')
 | 
					 | 
				
			||||||
            ->once()
 | 
					 | 
				
			||||||
            ->with('client')
 | 
					 | 
				
			||||||
            ->andReturn($data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Mocking the dependencies used within the client method
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $quickbooks->import('client');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->assertArrayHasKey('clients', $quickbooks->entity_count);
 | 
					 | 
				
			||||||
        $this->assertGreaterThan(0, $quickbooks->entity_count['clients']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $base_transformer = new BaseTransformer($this->company);
 | 
					 | 
				
			||||||
        $this->assertTrue($base_transformer->hasClient('Sonnenschein Family Store'));
 | 
					 | 
				
			||||||
        $contact = $base_transformer->getClient('Amy\'s Bird Sanctuary', '');
 | 
					 | 
				
			||||||
        $contact = Client::where('name', 'Amy\'s Bird Sanctuary')->first();
 | 
					 | 
				
			||||||
        $this->assertEquals('(650) 555-3311', $contact->phone);
 | 
					 | 
				
			||||||
        $this->assertEquals('Birds@Intuit.com', $contact->contacts()->first()->email);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testImportCallsGetDataOnceForProducts()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $data = (json_decode(file_get_contents(base_path('tests/Feature/Import/items.json')), true))['Item'];
 | 
					 | 
				
			||||||
        $hash = Str::random(32);
 | 
					 | 
				
			||||||
        Cache::put($hash.'-item', base64_encode(json_encode($data)), 360);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $quickbooks = Mockery::mock(Quickbooks::class, [[
 | 
					 | 
				
			||||||
            'hash' => $hash,
 | 
					 | 
				
			||||||
            'column_map' => ['item' => ['mapping' => []]],
 | 
					 | 
				
			||||||
            'skip_header' => true,
 | 
					 | 
				
			||||||
            'import_type' => 'quickbooks',
 | 
					 | 
				
			||||||
        ], $this->company ])->makePartial();
 | 
					 | 
				
			||||||
        $quickbooks->shouldReceive('getData')
 | 
					 | 
				
			||||||
            ->once()
 | 
					 | 
				
			||||||
            ->with('product')
 | 
					 | 
				
			||||||
            ->andReturn($data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Mocking the dependencies used within the client method
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $quickbooks->import('product');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->assertArrayHasKey('products', $quickbooks->entity_count);
 | 
					 | 
				
			||||||
        $this->assertGreaterThan(0, $quickbooks->entity_count['products']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $base_transformer = new BaseTransformer($this->company);
 | 
					 | 
				
			||||||
        $this->assertTrue($base_transformer->hasProduct('Gardening'));
 | 
					 | 
				
			||||||
        $product = Product::where('product_key', 'Pest Control')->first();
 | 
					 | 
				
			||||||
        $this->assertGreaterThanOrEqual(35, $product->price);
 | 
					 | 
				
			||||||
        $this->assertLessThanOrEqual(0, $product->quantity);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testImportCallsGetDataOnceForInvoices()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $data = (json_decode(file_get_contents(base_path('tests/Feature/Import/invoices.json')), true))['Invoice'];
 | 
					 | 
				
			||||||
        $hash = Str::random(32);
 | 
					 | 
				
			||||||
        Cache::put($hash.'-invoice', base64_encode(json_encode($data)), 360);
 | 
					 | 
				
			||||||
        $quickbooks = Mockery::mock(Quickbooks::class, [[
 | 
					 | 
				
			||||||
            'hash' => $hash,
 | 
					 | 
				
			||||||
            'column_map' => ['invoice' => ['mapping' => []]],
 | 
					 | 
				
			||||||
            'skip_header' => true,
 | 
					 | 
				
			||||||
            'import_type' => 'quickbooks',
 | 
					 | 
				
			||||||
        ], $this->company ])->makePartial();
 | 
					 | 
				
			||||||
        $quickbooks->shouldReceive('getData')
 | 
					 | 
				
			||||||
            ->once()
 | 
					 | 
				
			||||||
            ->with('invoice')
 | 
					 | 
				
			||||||
            ->andReturn($data);
 | 
					 | 
				
			||||||
        $quickbooks->import('invoice');
 | 
					 | 
				
			||||||
        $this->assertArrayHasKey('invoices', $quickbooks->entity_count);
 | 
					 | 
				
			||||||
        $this->assertGreaterThan(0, $quickbooks->entity_count['invoices']);
 | 
					 | 
				
			||||||
        $base_transformer = new BaseTransformer($this->company);
 | 
					 | 
				
			||||||
        $this->assertTrue($base_transformer->hasInvoice(1007));
 | 
					 | 
				
			||||||
        $invoice = Invoice::where('number', 1012)->first();
 | 
					 | 
				
			||||||
        $data = collect($data)->where('DocNumber', '1012')->first();
 | 
					 | 
				
			||||||
        $this->assertGreaterThanOrEqual($data['TotalAmt'], $invoice->amount);
 | 
					 | 
				
			||||||
        $this->assertEquals(count($data['Line']) - 1, count((array)$invoice->line_items));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected function tearDown(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Mockery::close();
 | 
					 | 
				
			||||||
        parent::tearDown();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11675
									
								
								tests/Feature/Import/Quickbooks/customer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11675
									
								
								tests/Feature/Import/Quickbooks/customer.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user