mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-23 20:00:33 -04:00
QB Sync
This commit is contained in:
parent
df52a48701
commit
01a42bb7e2
41
app/Casts/ClientSyncCast.php
Normal file
41
app/Casts/ClientSyncCast.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\DataMapper\ClientSync;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class ClientSyncCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
$data = json_decode($value, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$is = new ClientSync();
|
||||
$is->qb_id = $data['qb_id'];
|
||||
|
||||
return $is;
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
41
app/Casts/InvoiceSyncCast.php
Normal file
41
app/Casts/InvoiceSyncCast.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\DataMapper\InvoiceSync;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class InvoiceSyncCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
$data = json_decode($value, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$is = new InvoiceSync();
|
||||
$is->qb_id = $data['qb_id'];
|
||||
|
||||
return $is;
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
41
app/Casts/ProductSyncCast.php
Normal file
41
app/Casts/ProductSyncCast.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\DataMapper\ProductSync;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class ProductSyncCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
$data = json_decode($value, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ps = new ProductSync();
|
||||
$ps->qb_id = $data['qb_id'];
|
||||
|
||||
return $ps;
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
return [
|
||||
$key => json_encode([
|
||||
'qb_id' => $value->qb_id,
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
35
app/DataMapper/ClientSync.php
Normal file
35
app/DataMapper/ClientSync.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use App\Casts\ClientSyncCast;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
|
||||
/**
|
||||
* ClientSync.
|
||||
*/
|
||||
class ClientSync implements Castable
|
||||
{
|
||||
public string $qb_id;
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array<string, mixed> $arguments
|
||||
*/
|
||||
public static function castUsing(array $arguments): string
|
||||
{
|
||||
return ClientSyncCast::class;
|
||||
}
|
||||
|
||||
}
|
35
app/DataMapper/InvoiceSync.php
Normal file
35
app/DataMapper/InvoiceSync.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use App\Casts\InvoiceSyncCast;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
|
||||
/**
|
||||
* InvoiceSync.
|
||||
*/
|
||||
class InvoiceSync implements Castable
|
||||
{
|
||||
public string $qb_id;
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array<string, mixed> $arguments
|
||||
*/
|
||||
public static function castUsing(array $arguments): string
|
||||
{
|
||||
return InvoiceSyncCast::class;
|
||||
}
|
||||
|
||||
}
|
35
app/DataMapper/ProductSync.php
Normal file
35
app/DataMapper/ProductSync.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use App\Casts\ProductSyncCast;
|
||||
use Illuminate\Contracts\Database\Eloquent\Castable;
|
||||
|
||||
/**
|
||||
* ProductSync.
|
||||
*/
|
||||
class ProductSync implements Castable
|
||||
{
|
||||
public string $qb_id;
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @param array<string, mixed> $arguments
|
||||
*/
|
||||
public static function castUsing(array $arguments): string
|
||||
{
|
||||
return ProductSyncCast::class;
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ use App\Utils\Traits\MakesDates;
|
||||
use App\DataMapper\FeesAndLimits;
|
||||
use App\Models\Traits\Excludable;
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\ClientSync;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Services\Client\ClientService;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
@ -70,6 +71,7 @@ use Illuminate\Contracts\Translation\HasLocalePreference;
|
||||
* @property int|null $shipping_country_id
|
||||
* @property object|null $settings
|
||||
* @property object|null $group_settings
|
||||
* @property object|null $sync
|
||||
* @property bool $is_deleted
|
||||
* @property int|null $group_settings_id
|
||||
* @property string|null $vat_number
|
||||
@ -190,6 +192,7 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
'last_login' => 'timestamp',
|
||||
'tax_data' => 'object',
|
||||
'e_invoice' => 'object',
|
||||
'sync' => ClientSync::class,
|
||||
];
|
||||
|
||||
protected $touches = [];
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\DataMapper\InvoiceSync;
|
||||
use App\Utils\Ninja;
|
||||
use Laravel\Scout\Searchable;
|
||||
use Illuminate\Support\Carbon;
|
||||
@ -53,6 +54,7 @@ use App\Events\Invoice\InvoiceReminderWasEmailed;
|
||||
* @property bool $is_deleted
|
||||
* @property object|array|string $line_items
|
||||
* @property object|null $backup
|
||||
* @property object|null $sync
|
||||
* @property string|null $footer
|
||||
* @property string|null $public_notes
|
||||
* @property string|null $private_notes
|
||||
@ -213,6 +215,8 @@ class Invoice extends BaseModel
|
||||
'custom_surcharge_tax3' => 'bool',
|
||||
'custom_surcharge_tax4' => 'bool',
|
||||
'e_invoice' => 'object',
|
||||
'sync' => InvoiceSync::class,
|
||||
|
||||
];
|
||||
|
||||
protected $with = [];
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\DataMapper\ProductSync;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use League\CommonMark\CommonMarkConverter;
|
||||
@ -43,6 +44,7 @@ use League\CommonMark\CommonMarkConverter;
|
||||
* @property int|null $deleted_at
|
||||
* @property int|null $created_at
|
||||
* @property int|null $updated_at
|
||||
* @property object|null $sync
|
||||
* @property bool $is_deleted
|
||||
* @property float $in_stock_quantity
|
||||
* @property bool $stock_notification
|
||||
@ -100,6 +102,13 @@ class Product extends BaseModel
|
||||
'tax_id',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'updated_at' => 'timestamp',
|
||||
'created_at' => 'timestamp',
|
||||
'deleted_at' => 'timestamp',
|
||||
'sync' => ProductSync::class,
|
||||
];
|
||||
|
||||
public array $ubl_tax_map = [
|
||||
self::PRODUCT_TYPE_REVERSE_TAX => 'AE', // VAT_REVERSE_CHARGE =
|
||||
self::PRODUCT_TYPE_EXEMPT => 'E', // EXEMPT_FROM_TAX =
|
||||
|
@ -52,12 +52,12 @@ class QuickbooksSync implements ShouldQueue
|
||||
'product' => 'Item',
|
||||
'client' => 'Customer',
|
||||
'invoice' => 'Invoice',
|
||||
'quote' => 'Estimate',
|
||||
'purchase_order' => 'PurchaseOrder',
|
||||
'payment' => 'Payment',
|
||||
// 'quote' => 'Estimate',
|
||||
// 'purchase_order' => 'PurchaseOrder',
|
||||
// 'payment' => 'Payment',
|
||||
'sales' => 'SalesReceipt',
|
||||
'vendor' => 'Vendor',
|
||||
'expense' => 'Purchase',
|
||||
// 'vendor' => 'Vendor',
|
||||
// 'expense' => 'Purchase',
|
||||
];
|
||||
|
||||
private QuickbooksService $qbs;
|
||||
@ -81,8 +81,8 @@ class QuickbooksSync implements ShouldQueue
|
||||
$this->qbs = new QuickbooksService($this->company);
|
||||
$this->settings = $this->company->quickbooks->settings;
|
||||
|
||||
nlog("here we go!");
|
||||
foreach($this->entities as $key => $entity) {
|
||||
|
||||
if(!$this->syncGate($key, 'pull')) {
|
||||
continue;
|
||||
}
|
||||
@ -95,31 +95,46 @@ class QuickbooksSync implements ShouldQueue
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a sync is allowed based on the settings
|
||||
*
|
||||
* @param string $entity
|
||||
* @param string $direction
|
||||
* @return bool
|
||||
*/
|
||||
private function syncGate(string $entity, string $direction): bool
|
||||
{
|
||||
return (bool) $this->settings[$entity]['sync'] && in_array($this->settings[$entity]['direction'], [$direction,'bidirectional']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the gate for a given entity
|
||||
*
|
||||
* @param string $entity
|
||||
* @return bool
|
||||
*/
|
||||
private function updateGate(string $entity): bool
|
||||
{
|
||||
return (bool) $this->settings[$entity]['sync'] && $this->settings[$entity]['update_record'];
|
||||
}
|
||||
|
||||
// private function harvestQbEntityName(string $entity): string
|
||||
// {
|
||||
// return $this->entities[$entity];
|
||||
// }
|
||||
|
||||
private function processEntitySync(string $entity, $records)
|
||||
/**
|
||||
* Processes the sync for a given entity
|
||||
*
|
||||
* @param string $entity
|
||||
* @param mixed $records
|
||||
* @return void
|
||||
*/
|
||||
private function processEntitySync(string $entity, $records): void
|
||||
{
|
||||
match($entity){
|
||||
'client' => $this->syncQbToNinjaClients($records),
|
||||
'product' => $this->syncQbToNinjaProducts($records),
|
||||
'invoice' => $this->syncQbToNinjaInvoices($records),
|
||||
'sales' => $this->syncQbToNinjaInvoices($records),
|
||||
'vendor' => $this->syncQbToNinjaVendors($records),
|
||||
// 'client' => $this->syncQbToNinjaClients($records),
|
||||
'product' => $this->qbs->product->syncToNinja($records),
|
||||
// 'invoice' => $this->syncQbToNinjaInvoices($records),
|
||||
// 'sales' => $this->syncQbToNinjaInvoices($records),
|
||||
// 'vendor' => $this->syncQbToNinjaVendors($records),
|
||||
// 'quote' => $this->syncInvoices($records),
|
||||
'expense' => $this->syncQbToNinjaExpenses($records),
|
||||
// 'expense' => $this->syncQbToNinjaExpenses($records),
|
||||
// 'purchase_order' => $this->syncInvoices($records),
|
||||
// 'payment' => $this->syncPayment($records),
|
||||
default => false,
|
||||
@ -140,6 +155,7 @@ class QuickbooksSync implements ShouldQueue
|
||||
nlog($ninja_invoice_data);
|
||||
|
||||
$payment_ids = $ninja_invoice_data['payment_ids'] ?? [];
|
||||
|
||||
$client_id = $ninja_invoice_data['client_id'] ?? null;
|
||||
|
||||
if(is_null($client_id))
|
||||
@ -152,7 +168,7 @@ class QuickbooksSync implements ShouldQueue
|
||||
$invoice->fill($ninja_invoice_data);
|
||||
$invoice->saveQuietly();
|
||||
|
||||
$invoice = $invoice->calc()->getInvoice()->service()->markSent()->save();
|
||||
$invoice = $invoice->calc()->getInvoice()->service()->markSent()->createInvitations()->save();
|
||||
|
||||
foreach($payment_ids as $payment_id)
|
||||
{
|
||||
@ -196,7 +212,8 @@ class QuickbooksSync implements ShouldQueue
|
||||
$search = Invoice::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('number', $ninja_invoice_data['number']);
|
||||
// ->where('number', $ninja_invoice_data['number']);
|
||||
->where('sync->qb_id', $ninja_invoice_data['id']);
|
||||
|
||||
if($search->count() == 0) {
|
||||
//new invoice
|
||||
@ -400,27 +417,7 @@ class QuickbooksSync implements ShouldQueue
|
||||
return null;
|
||||
}
|
||||
|
||||
private function findProduct(string $key): ?Product
|
||||
{
|
||||
$search = Product::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('hash', $key);
|
||||
|
||||
if($search->count() == 0) {
|
||||
//new product
|
||||
$product = ProductFactory::create($this->company->id, $this->company->owner()->id);
|
||||
$product->hash = $key;
|
||||
|
||||
return $product;
|
||||
} elseif($search->count() == 1) {
|
||||
return $this->settings['product']['update_record'] ? $search->first() : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function middleware()
|
||||
{
|
||||
|
30
app/Services/Quickbooks/Models/QbInvoice.php
Normal file
30
app/Services/Quickbooks/Models/QbInvoice.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Services\Quickbooks\Models;
|
||||
|
||||
|
||||
use App\Services\Quickbooks\QuickbooksService;
|
||||
|
||||
class QbInvoice
|
||||
{
|
||||
|
||||
public function __construct(public QuickbooksService $service)
|
||||
{
|
||||
}
|
||||
|
||||
public function find(int $id)
|
||||
{
|
||||
return $this->service->sdk->FindById('Invoice', $id);
|
||||
}
|
||||
|
||||
|
||||
}
|
76
app/Services/Quickbooks/Models/QbProduct.php
Normal file
76
app/Services/Quickbooks/Models/QbProduct.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Services\Quickbooks\Models;
|
||||
|
||||
use App\DataMapper\ProductSync;
|
||||
use App\Services\Quickbooks\QuickbooksService;
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Factory\ProductFactory;
|
||||
use App\Services\Quickbooks\Transformers\ProductTransformer;
|
||||
|
||||
|
||||
class QbProduct
|
||||
{
|
||||
public function __construct(public QuickbooksService $service)
|
||||
{
|
||||
}
|
||||
|
||||
public function find(int $id)
|
||||
{
|
||||
return $this->service->sdk->FindById('Item', $id);
|
||||
}
|
||||
|
||||
|
||||
public function syncToNinja(array $records)
|
||||
{
|
||||
|
||||
$product_transformer = new ProductTransformer($this->service->company);
|
||||
|
||||
foreach ($records as $record) {
|
||||
|
||||
$ninja_data = $product_transformer->qbToNinja($record);
|
||||
|
||||
if ($product = $this->findProduct($ninja_data['id'])) {
|
||||
$product->fill($ninja_data);
|
||||
$product->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function findProduct(string $key): ?Product
|
||||
{
|
||||
$search = Product::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->service->company->id)
|
||||
->where('sync->qb_id', $key);
|
||||
|
||||
if($search->count() == 0) {
|
||||
|
||||
$product = ProductFactory::create($this->service->company->id, $this->service->company->owner()->id);
|
||||
|
||||
$sync = new ProductSync();
|
||||
$sync->qb_id = $key;
|
||||
$product->sync = $sync;
|
||||
|
||||
return $product;
|
||||
|
||||
} elseif($search->count() == 1) {
|
||||
return $this->service->settings['product']['update_record'] ? $search->first() : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -11,16 +11,19 @@
|
||||
|
||||
namespace App\Services\Quickbooks;
|
||||
|
||||
use App\Factory\ClientContactFactory;
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\ProductFactory;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Product;
|
||||
use App\Services\Quickbooks\Jobs\QuickbooksSync;
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\ProductFactory;
|
||||
use App\Factory\ClientContactFactory;
|
||||
use App\DataMapper\QuickbooksSettings;
|
||||
use QuickBooksOnline\API\Core\CoreConstants;
|
||||
use App\Services\Quickbooks\Models\QbInvoice;
|
||||
use App\Services\Quickbooks\Models\QbProduct;
|
||||
use App\Services\Quickbooks\Jobs\QuickbooksSync;
|
||||
use QuickBooksOnline\API\DataService\DataService;
|
||||
use App\Services\Quickbooks\Transformers\ClientTransformer;
|
||||
use App\Services\Quickbooks\Transformers\InvoiceTransformer;
|
||||
@ -31,9 +34,15 @@ class QuickbooksService
|
||||
{
|
||||
public DataService $sdk;
|
||||
|
||||
public QbInvoice $invoice;
|
||||
|
||||
public QbProduct $product;
|
||||
|
||||
public array $settings;
|
||||
|
||||
private bool $testMode = true;
|
||||
|
||||
public function __construct(private Company $company)
|
||||
public function __construct(public Company $company)
|
||||
{
|
||||
$this->init();
|
||||
}
|
||||
@ -61,6 +70,12 @@ class QuickbooksService
|
||||
$this->sdk->setMinorVersion("73");
|
||||
$this->sdk->throwExceptionOnError(true);
|
||||
|
||||
$this->invoice = new QbInvoice($this);
|
||||
|
||||
$this->product = new QbProduct($this);
|
||||
|
||||
$this->settings = $this->company->quickbooks->settings;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,8 @@ class BaseTransformer
|
||||
$client = Client::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('number', $customer_reference_id)
|
||||
// ->where('number', $customer_reference_id)
|
||||
->where('sync->qb_id', $customer_reference_id)
|
||||
->first();
|
||||
|
||||
return $client ? $client->id : null;
|
||||
|
@ -38,6 +38,7 @@ class InvoiceTransformer extends BaseTransformer
|
||||
$client_id = $this->getClientId(data_get($qb_data, 'CustomerRef.value', null));
|
||||
|
||||
return $client_id ? [
|
||||
'id' => data_get($qb_data, 'Id.value', false),
|
||||
'client_id' => $client_id,
|
||||
'number' => data_get($qb_data, 'DocNumber', false),
|
||||
'date' => data_get($qb_data, 'TxnDate', now()->format('Y-m-d')),
|
||||
|
@ -33,7 +33,7 @@ class ProductTransformer extends BaseTransformer
|
||||
nlog(data_get($data, 'Id', null));
|
||||
|
||||
return [
|
||||
'hash' => data_get($data, 'Id.value', null),
|
||||
'id' => data_get($data, 'Id.value', null),
|
||||
'product_key' => data_get($data, 'Name', data_get($data, 'FullyQualifiedName','')),
|
||||
'notes' => data_get($data, 'Description', ''),
|
||||
'cost' => data_get($data, 'PurchaseCost', 0),
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('clients', function (Blueprint $table) {
|
||||
$table->text('sync')->nullable();
|
||||
});
|
||||
|
||||
Schema::table('invoices', function (Blueprint $table) {
|
||||
$table->text('sync')->nullable();
|
||||
});
|
||||
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->text('sync')->nullable();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
@ -12,11 +12,14 @@ use Tests\MockAccountData;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Mockery;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Product;
|
||||
use App\Models\Invoice;
|
||||
use App\Services\Quickbooks\QuickbooksService;
|
||||
use Illuminate\Support\Str;
|
||||
use ReflectionClass;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use QuickBooksOnline\API\Facades\Invoice as QbInvoice;
|
||||
|
||||
class QuickbooksTest extends TestCase
|
||||
{
|
||||
@ -30,12 +33,24 @@ class QuickbooksTest extends TestCase
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->markTestSkipped('no bueno');
|
||||
|
||||
if(config('ninja.is_travis'))
|
||||
{
|
||||
$this->markTestSkipped('No need to run this test on Travis');
|
||||
}
|
||||
elseif(Company::whereNotNull('quickbooks')->count() == 0){
|
||||
$this->markTestSkipped('No need to run this test on Travis');
|
||||
}
|
||||
}
|
||||
|
||||
public function testCustomerSync()
|
||||
public function testCreateInvoiceInQb()
|
||||
{
|
||||
$data = (json_decode(file_get_contents(base_path('tests/Feature/Import/Quickbooks/customers.json')), false));
|
||||
|
||||
$c = Company::whereNotNull('quickbooks')->first();
|
||||
|
||||
$qb = new QuickbooksService($c);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user