geccomedia/weclapp
最新稳定版本:v7.0.0
Composer 安装命令:
composer require geccomedia/weclapp
包简介
Weclapp api via laravel eloquent
关键字:
README 文档
README
This repo implements most of the Laravel Eloquent Model for the Weclapp web api.
Contents
- Installation
- Usage
- Available Models
- Custom Models
- Mass Assignments
- Relations
- Additional Properties
- Custom Actions
- Read-only Models
- Embedded Sub-Objects
- Sub Entities
- Logging
- Party-type Models
- Boolean Filters
- System & Job Utility APIs
- License & Copyright
Installation
Require this package with Composer
composer require geccomedia/weclapp
Add the variables to your .env:
WECLAPP_BASE_URL=https://your-subdomain.weclapp.com/webapp/api/v1/
WECLAPP_API_KEY=your-key
Usage
Use existing models from the Geccomedia\Weclapp\Models namespace.
Most Eloquent methods are implemented within the limitations of the web API.
<?php use Geccomedia\Weclapp\Models\Customer; $customer = Customer::where('company', 'Your Company Name') ->firstOrFail();
Available Models
Over 150 models are provided, covering all queryable Weclapp API endpoints —
including SalesOrder, Customer, Article, Shipment, PurchaseOrder,
Invoice, Ticket, and many more. Every model has full @property annotations
for IDE autocompletion.
Custom Models
The API route is derived automatically from the class name using lcfirst(ClassName),
so SalesOrder maps to salesOrder, Article maps to article, etc. You only need to
declare $table when your class name does not match the API route:
<?php namespace Your\Custom\Namespace; use Geccomedia\Weclapp\Model; class MyOrder extends Model { /** * Override only when the class name doesn't match the API route. * * @var string */ protected $table = 'salesOrder'; }
Mass Assignments
If you want to do mass assignment please use unguard and reguard:
$customer = new \Geccomedia\Weclapp\Models\Customer(); \Geccomedia\Weclapp\Models\Customer::unguard(); $customer->fill(['partyType' => 'ORGANIZATION']); \Geccomedia\Weclapp\Models\Customer::reguard();
Relations
Models declare belongsTo and hasMany relationships using Weclapp's
camelCase foreign key convention (e.g. customerId, not customer_id).
Eager loading (recommended — single batched request)
Use with() to load related models in one extra request instead of one per record:
// 2 HTTP requests total: one for orders, one batched party lookup $orders = SalesOrder::with('customer')->get(); foreach ($orders as $order) { echo $order->customer->company; }
Lazy loading (N+1)
Without with(), each relation access fires its own HTTP request:
$orders = SalesOrder::get(); // 1 request foreach ($orders as $order) { echo $order->customer->company; // 1 request per order }
Inverse relations (hasMany)
Common inverse relations are defined, so you can traverse from either side:
$customer = Customer::find('1'); $customer->salesOrders()->get(); // GET /salesOrder?customerId-eq=1 $customer->shipments()->get(); // GET /shipment?customerId-eq=1 $customer->quotations()->get(); // GET /quotation?customerId-eq=1 $customer->salesInvoices()->get(); // GET /salesInvoice?customerId-eq=1 $warehouse->warehouseStock()->get(); // GET /warehouseStock?warehouseId-eq=1 $salesOrder->shipments()->get(); // GET /shipment?salesOrderId-eq=1 $salesOrder->salesInvoices()->get(); // GET /salesInvoice?salesOrderId-eq=1 $article->articlePrices()->get(); // GET /articlePrice?articleId-eq=1 $supplier->purchaseOrders()->get(); // GET /purchaseOrder?supplierId-eq=1
Additional Properties
Weclapp can return extra computed fields that are not included by default.
Request them with withProperties():
// Includes the orderItems and tags fields in the response $orders = SalesOrder::withProperties('orderItems', 'tags')->get(); // → GET /salesOrder?additionalProperties=orderItems,tags
This can be combined with select() and other query methods:
SalesOrder::select('id', 'orderNumber') ->withProperties('orderItems') ->where('status', 'ORDER_ENTRY_IN_PROGRESS') ->get();
Custom Actions
Weclapp exposes many action endpoints beyond standard CRUD. Call them via
action() at the class level or callAction() on a model instance.
Collection-level actions
// POST /salesOrder/defaultValuesForCreate $defaults = SalesOrder::action('defaultValuesForCreate'); // POST /tax/configureSalesTaxes {"taxRateType": "STANDARD"} Tax::action('configureSalesTaxes', ['taxRateType' => 'STANDARD']);
Instance-level actions
$order = SalesOrder::find('123'); // POST /salesOrder/id/123/createShipment $order->newQuery()->callAction('createShipment'); // POST /salesOrder/id/123/createSalesInvoice {"invoiceDate": 1234567890000} $order->newQuery()->callAction('createSalesInvoice', ['invoiceDate' => 1234567890000]); // POST /quotation/id/456/accept $quotation->newQuery()->callAction('accept');
All actions return the decoded JSON response body as an array, or null if
the response has no body.
Read-only Models
Some Weclapp endpoints are read-only (no create or delete). Attempting to
save() a new instance or delete() an existing one on these models will
throw a NotSupportedException immediately, without making an HTTP request.
Mutation restrictions are expressed via three composable traits:
| Trait | Blocks | Swagger condition |
|---|---|---|
NoCreate |
save() on new instances |
No POST /resource endpoint |
NoUpdate |
save() on existing instances |
No PUT /resource/id/{id} endpoint |
NoDelete |
delete() |
No DELETE /resource/id/{id} endpoint |
IsReadOnly (use NoCreate, NoUpdate, NoDelete) and IsUpdatableOnly (use NoCreate, NoDelete) are convenience aliases for common combinations.
Embedded Sub-Objects
Weclapp embeds related data directly in API responses rather than using
separate endpoints. These are automatically hydrated into typed SubModel
value objects on read.
$order = SalesOrder::find('123'); // Object-style access (new) echo $order->orderItems[0]->articleId; echo $order->recordAddress->city; // Array-style access (still works — SubModel implements ArrayAccess) echo $order->orderItems[0]['articleId'];
toArray() and toJson() always return plain nested arrays, so serialisation
and API writes are unaffected.
Sub Entities
Weclapp treats some models as sub-entities that belong to a parent. For these,
supply the parent entity with whereEntity($name, $id):
$comments = Comment::whereEntity('customer', 123)->orderBy('id')->get();
Without the call to whereEntity the API will return an error.
See #22 for more information.
Logging
To inspect the HTTP requests being made, enable the connection query log:
use Geccomedia\Weclapp\Connection; app(Connection::class)->enableQueryLog(); \Geccomedia\Weclapp\Models\Customer::create(['name' => 'Test']); app(Connection::class)->getQueryLog();
Party-type Models
Weclapp stores customers, suppliers, leads, and contacts all as records in the
single /party endpoint, differentiated by boolean role flags and a leadStatus
field. The four convenience model classes each apply a global query scope so
they automatically filter to the right subset:
| Class | Route | Filter applied |
|---|---|---|
Customer |
/party |
customer = true |
Supplier |
/party |
supplier = true |
Lead |
/party |
leadStatus is set and not CONVERTED |
Contact |
/party |
partyType = PERSON |
The scopes are transparent — any extra where() clauses stack alongside them:
// GET /party?customer-eq=true&company-eq=Acme&pageSize=100 $customers = Customer::where('company', 'Acme')->get(); // GET /party?supplier-eq=true&pageSize=100 $suppliers = Supplier::all(); // GET /party?leadStatus-notnull=&leadStatus-ne=CONVERTED&pageSize=100 $leads = Lead::all(); // GET /party?partyType-eq=PERSON&pageSize=100 $contacts = Contact::all();
A single weclapp party can carry multiple roles simultaneously (e.g.
customer = true and supplier = true). Party::all() returns every party
record unfiltered when you need to query across roles.
leadStatus values
| Value | Meaning |
|---|---|
NEW |
Just entered the funnel |
PREQUALIFIED |
Initial screening done |
QUALIFIED |
Sales-ready |
CONVERTED |
Graduated to a customer — excluded from Lead, appears under Customer |
DISQUALIFIED |
Rejected from funnel |
Boolean Filters
PHP true and false values passed to where() or whereIn() are
automatically serialised to the strings "true" and "false" that the
weclapp API expects:
// GET /party?customer-eq=true&... Customer::where('customer', true)->get(); // GET /party?customerBlocked-eq=false&... Customer::where('customerBlocked', false)->get(); // GET /article?active-in=["true","false"]&... Article::whereIn('active', [true, false])->get();
System & Job Utility APIs
Weclapp exposes a handful of endpoints under /system and /job that have no
CRUD model. Two dedicated classes wrap these as typed methods.
SystemApi
use Geccomedia\Weclapp\SystemApi; $api = app(SystemApi::class); // GET /system/permissions → string[] // Returns the permission slugs granted to the current API key. $permissions = $api->permissions(); // e.g. ['party:read', 'salesOrder:read', 'salesOrder:write', ...] // GET /system/licenses → array of {name: string, permissions: string[]} // Returns the active licence modules and their included permissions. $licenses = $api->licenses(); // e.g. [['name' => 'SALES', 'permissions' => ['salesOrder:read', ...]], ...] // GET /system/demoTestSystemInfo // Returns whether a demo instance can be created from this tenant. $info = $api->demoTestSystemInfo(); // e.g. ['createPossible' => true, 'creationInProgress' => false, ...] // POST /system/createDemoTestSystem // Creates a demo copy of this tenant. Preset: 'NONE', 'PROD_SYSTEM', or 'TEMPLATE_SYSTEM'. $api->createDemoTestSystem('My Test System', 'PROD_SYSTEM'); $api->createDemoTestSystem('My Test System', 'PROD_SYSTEM', allUsers: true);
JobApi
Weclapp runs long-running background jobs asynchronously. Use JobApi to poll
or cancel them by type.
use Geccomedia\Weclapp\JobApi; $api = app(JobApi::class); // GET /job/status?type=INVENTORY_BOOKING // Returns the current status and progress of the named background job. $status = $api->status('INVENTORY_BOOKING'); // e.g. ['type' => 'INVENTORY_BOOKING', 'status' => 'EXECUTING', 'progress' => ['current' => 42, 'total' => 100]] // GET /job/abort?type=INVENTORY_BOOKING // Requests cancellation of a running job. $result = $api->abort('INVENTORY_BOOKING');
Valid type values are the SCREAMING_SNAKE_CASE job names from the Weclapp
API spec (e.g. INVENTORY_BOOKING, MATERIAL_PLANNING_RUN,
MASS_SHIPMENT_CREATION, ACCOUNTING_EXPORT, and many more).
License & Copyright
Copyright © 2017–2026 Gecco Media GmbH
统计信息
- 总下载量: 2.15k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 7
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2017-12-14