承接 jeffgreco13/laravel-wave 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

jeffgreco13/laravel-wave

Composer 安装命令:

composer create-project jeffgreco13/laravel-wave

包简介

A wrapper to use the Wave GraphQL API in your Laravel apps.

README 文档

README

A Laravel package for the Wave Accounting GraphQL API. Query your Wave data, sync it to local Eloquent models, and manage customers, invoices, products, and more — all via queued jobs and Artisan commands.

Requirements

Installation

composer require jeffgreco13/laravel-wave

Publish the config file:

php artisan vendor:publish --tag=wave-config

Publish the migrations (optional — only needed if you want local sync):

php artisan vendor:publish --tag=wave-migrations
php artisan migrate

Configuration

Add to your .env:

WAVE_ACCESS_TOKEN=your_oauth_token_here
WAVE_BUSINESS_ID=your_wave_business_uuid_here

Full config/wave.php reference:

return [
    'access_token' => env('WAVE_ACCESS_TOKEN'),
    'graphql_uri'  => env('WAVE_GRAPHQL_URI', 'https://gql.waveapps.com/graphql/public'),
    'business_id'  => env('WAVE_BUSINESS_ID'),

    // Override with your own Eloquent models (see "Custom Models" below)
    'models' => [
        'customer'  => \Jeffgreco13\Wave\Models\WaveCustomer::class,
        'invoice'   => \Jeffgreco13\Wave\Models\WaveInvoice::class,
        'product'   => \Jeffgreco13\Wave\Models\WaveProduct::class,
        'sales_tax' => \Jeffgreco13\Wave\Models\WaveSalesTax::class,
        'vendor'    => \Jeffgreco13\Wave\Models\WaveVendor::class,
        'business'  => \Jeffgreco13\Wave\Models\WaveBusiness::class,
        'account'   => \Jeffgreco13\Wave\Models\WaveAccount::class,
    ],

    'sync' => [
        'chunk_size' => 150, // records per page during sync
    ],
];

Basic Usage

Inject WaveService or resolve it from the container:

use Jeffgreco13\Wave\WaveService;

class InvoiceController extends Controller
{
    public function __construct(protected WaveService $wave) {}

    public function index()
    {
        // Returns a Collection of Node objects
        return $this->wave->getCustomers(['page' => 1, 'pageSize' => 20]);
    }
}

Nodes support both array and property access:

foreach ($this->wave->getAllCustomers() as $customer) {
    echo $customer['name'];   // array access
    echo $customer->email;    // property access
}

Available API Methods

Method Description
getCustomers($vars) Paginated customer list
getAllCustomers($vars) All customers (handles pagination)
createCustomer($input) Create a new customer
patchCustomer($input) Update a customer (requires id)
deleteCustomer($customerId) Delete a customer
getInvoices($vars) Paginated invoice list
getAllInvoices($vars) All invoices
createInvoice($input) Create an invoice
approveInvoice($invoiceId) Approve a draft invoice
sendInvoice($input) Send an invoice by email
getAllProducts() All products
getAllTaxes() All sales taxes
getVendors($vars) Paginated vendor list
getAllVendors() All vendors
getAccounts($vars) Paginated chart-of-accounts
getAllAccounts() All chart-of-accounts entries
getAccount($accountId) Single account
getAllBusinesses() All businesses on the account
getBusiness($id) Single business
getUser() Authenticated user
rawQuery($query, $variables) Execute a custom GraphQL query

Pagination

$wave->getCustomers(['page' => 1, 'pageSize' => 20]);

while ($wave->hasNextPage()) {
    $wave->nextPage();
    $wave->getCustomers();
}

Data Sync

Sync jobs persist Wave data to your local database. All jobs implement ShouldQueue.

Full Sync

Fetches all records from Wave and upserts them locally. After all pages are processed, any local record whose wave_id was not seen in Wave is deleted (orphan cleanup).

use Jeffgreco13\Wave\Jobs\SyncCustomersFromWave;

// Queue
SyncCustomersFromWave::dispatch();

// Or via Artisan
php artisan wave:sync-customers

Incremental Sync

Only fetches records modified after a given date. Never deletes local records — a missing record just means it was not recently modified, not that it was deleted.

// Sync records modified in the last 24 hours
SyncCustomersFromWave::dispatch(since: now()->subDay());
# Specific date
php artisan wave:sync-customers --since="2024-06-01"

# Automatically use the most recently synced local record's wave_modified_at
php artisan wave:sync-customers --since=last

Sync All Entities

# Queue all sync jobs
php artisan wave:sync-all

# Run synchronously
php artisan wave:sync-all --sync

# With business override
php artisan wave:sync-all --business-id=QnVzaW5lc3M6...

Querying Local Wave Models

use Jeffgreco13\Wave\Models\WaveCustomer;
use Jeffgreco13\Wave\Models\WaveInvoice;

// Active customers
WaveCustomer::active()->get();

// Find by Wave ID
WaveCustomer::where('wave_id', $id)->first();

// Unpaid invoices for a customer
WaveInvoice::active()->forCustomer($waveCustomerId)->status('UNPAID')->get();

Customer CRUD via Jobs

use Jeffgreco13\Wave\Jobs\CreateWaveCustomer;
use Jeffgreco13\Wave\Jobs\UpdateWaveCustomer;
use Jeffgreco13\Wave\Jobs\DeleteWaveCustomer;

// Create in Wave and upsert locally
CreateWaveCustomer::dispatch([
    'name'  => 'Acme Corp',
    'email' => 'billing@acme.com',
]);

// Update (must include 'id' — Wave's customer UUID)
UpdateWaveCustomer::dispatch([
    'id'    => 'QnVzdG9tZXI6...',
    'email' => 'new@acme.com',
]);

// Delete from Wave and remove the local record
DeleteWaveCustomer::dispatch('QnVzdG9tZXI6...');

Custom Models

To use your own Eloquent model, implement the HasWaveSync trait and register it in config/wave.php.

// app/Models/Customer.php
use Jeffgreco13\Wave\Traits\HasWaveSync;

class Customer extends Model
{
    use HasWaveSync;

    protected $fillable = ['wave_id', 'company_name', 'email', 'currency_code'];

    /**
     * Map local column names to Wave API field paths.
     * Use dot-notation for nested Wave objects.
     */
    public function waveAttributeMap(): array
    {
        return [
            'wave_id'       => 'id',
            'company_name'  => 'name',
            'email'         => 'email',
            'currency_code' => 'currency.code',
        ];
    }
}

Register in config/wave.php:

'models' => [
    'customer' => \App\Models\Customer::class,
],

All sync jobs (SyncCustomersFromWave, CreateWaveCustomer, etc.) will use your model automatically.

Available Artisan Commands

Command Description
wave:sync-customers Sync customers from Wave
wave:sync-all Sync all entities
wave:pull-currencies Cache Wave currency list locally

Options for wave:sync-customers and wave:sync-all:

Option Description
--since="YYYY-MM-DD" Incremental sync from a date
--since=last Incremental from most recent local record
--business-id= Override the configured business ID
--sync Run synchronously (skip queue)
--fresh Truncate the local table first (full sync only)

Available Sync Jobs

Job Supports $since? Deletes orphans?
SyncCustomersFromWave Yes Full sync only
SyncInvoicesFromWave Yes Full sync only
SyncProductsFromWave No Always (full sync)
SyncSalesTaxesFromWave No Always
SyncVendorsFromWave No Always
SyncBusinessesFromWave No Always
SyncAccountsFromWave No Always

Data Enums

Use built-in enums for sort/filter values:

use Jeffgreco13\Wave\Data\CustomerSort;
use Jeffgreco13\Wave\Data\InvoiceSort;
use Jeffgreco13\Wave\Data\InvoiceStatus;
use Jeffgreco13\Wave\Data\InvoiceCreateStatus;
use Jeffgreco13\Wave\Data\ProductSort;

$wave->getCustomers(['sort' => CustomerSort::NAME_ASC]);
$wave->getInvoices(['status' => InvoiceStatus::UNPAID]);

Laravel Boost

This package includes AI guidelines and a developer skill for Laravel Boost. After installing Boost in your app, run:

php artisan boost:install
# or
php artisan boost:update --discover

Boost will automatically load the wave-development guidelines and skill to help AI agents write correct Wave integration code.

Changelog / Upgrade Guide

v2.0

  • Breaking: Config key changed from laravel-wave to wave. Update any manual config('laravel-wave.*') calls to config('wave.*').
  • Added local Eloquent model sync (wave_customers, wave_invoices, wave_products, wave_sales_taxes, wave_vendors, wave_businesses, wave_accounts)
  • Added HasWaveSync trait for custom model mapping
  • Added sync jobs for all entities with full/incremental modes and orphan deletion
  • Added wave:sync-customers, wave:sync-all Artisan commands
  • Added ManagesVendors and ManagesAccounts traits to WaveService
  • Added deleteCustomer() to ManagesCustomers
  • Laravel Boost integration (resources/boost/guidelines/ and resources/boost/skills/)

License

MIT

jeffgreco13/laravel-wave 适用场景与选型建议

jeffgreco13/laravel-wave 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 355 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 11 月 22 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 jeffgreco13/laravel-wave 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 jeffgreco13/laravel-wave 我们能提供哪些服务?
定制开发 / 二次开发

基于 jeffgreco13/laravel-wave 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 355
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 19
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-11-22