cabloy 5.1.149 → 5.1.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cabloy-version +1 -1
- package/.claude/commands/release.md +12 -1
- package/.claude/hooks/contract-loop-gate.ts +35 -17
- package/.claude/skills/cabloy-backend-scaffold/SKILL.md +4 -3
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +3 -2
- package/.claude/skills/cabloy-contract-loop/SKILL.md +4 -3
- package/.claude/skills/cabloy-domain-planning/SKILL.md +4 -3
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +5 -3
- package/.claude/skills/cabloy-master-detail/SKILL.md +4 -3
- package/.claude/skills/cabloy-module-removal/SKILL.md +5 -4
- package/.claude/skills/cabloy-resource-field-update/SKILL.md +8 -5
- package/.claude/skills/cabloy-spec-execution/SKILL.md +169 -0
- package/.claude/skills/cabloy-spec-execution/evals/evals.json +71 -0
- package/.claude/skills/cabloy-spec-execution/references/execution-protocol.md +137 -0
- package/.claude/skills/cabloy-spec-execution/references/status-and-evidence.md +117 -0
- package/.claude/skills/cabloy-spec-generation/SKILL.md +227 -0
- package/.claude/skills/cabloy-spec-generation/evals/evals.json +83 -0
- package/.claude/skills/cabloy-spec-generation/references/repo-aware-discovery.md +101 -0
- package/.claude/skills/cabloy-spec-generation/references/repo-specs-document-set.md +267 -0
- package/.claude/skills/cabloy-spec-generation/references/traceability-and-status-rules.md +135 -0
- package/.claude/skills/cabloy-spec-generation/scripts/generate-implementation-charts.mjs +350 -0
- package/.claude/skills/cabloy-spec-generation/scripts/generate-implementation-charts.test.mjs +202 -0
- package/.claude/skills/cabloy-workflow/SKILL.md +21 -10
- package/.claude/skills/cabloy-workflow/evals/evals.json +8 -2
- package/.claude/skills/cabloy-workflow/references/edition-detection.md +5 -3
- package/.claude/skills/cabloy-zova-source-reading/SKILL.md +4 -3
- package/CHANGELOG.md +41 -0
- package/CLAUDE.md +12 -11
- package/package.json +4 -2
- package/repo-docs/.vitepress/config.mjs +4 -0
- package/repo-docs/ai/docs-skills-rules-mapping.md +6 -6
- package/repo-docs/ai/future-skill-roadmap.md +2 -2
- package/repo-docs/ai/introduction.md +5 -5
- package/repo-docs/ai/playbook-contract-regeneration.md +3 -9
- package/repo-docs/ai/repo-guidance.md +5 -4
- package/repo-docs/ai/rules-and-config.md +2 -2
- package/repo-docs/ai/virtual-decorator-guidance.md +1 -3
- package/repo-docs/backend/cache-guide.md +36 -0
- package/repo-docs/backend/dto-guide.md +7 -6
- package/repo-docs/backend/dto-infer-generation.md +25 -5
- package/repo-docs/backend/introduction.md +1 -1
- package/repo-docs/backend/migration-and-changes.md +27 -2
- package/repo-docs/backend/model-guide.md +1 -1
- package/repo-docs/backend/resource-field-update.md +156 -0
- package/repo-docs/frontend/a-model-under-the-hood.md +38 -0
- package/repo-docs/frontend/a-openapi-under-the-hood.md +13 -2
- package/repo-docs/frontend/form-layout-guide.md +26 -9
- package/repo-docs/frontend/model-resource-best-practices.md +2 -0
- package/repo-docs/frontend/model-resource-cookbook.md +7 -1
- package/repo-docs/frontend/router-tabs-introduction.md +2 -4
- package/repo-docs/frontend/use-state-data-best-practices.md +44 -0
- package/repo-docs/frontend/zova-form-source-reading-map.md +26 -9
- package/repo-docs/frontend/zova-form-under-the-hood.md +11 -0
- package/repo-docs/fullstack/a-pay-payment-suite.md +1 -1
- package/repo-docs/fullstack/contract-loop-playbook.md +4 -0
- package/repo-docs/fullstack/one-to-one-companion-resource-guide.md +2 -2
- package/repo-docs/reference/package-map.md +1 -1
- package/repo-e2e/specs/a-commerce.spec.ts +40 -0
- package/scripts/release.ts +48 -1
- package/scripts/upgrade.ts +18 -7
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/controller/{{resourceName}}.ts_ +2 -2
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/pnpm-lock.yaml +83 -75
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +108 -108
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +12 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/sku.ts +19 -1
- package/vona/src/suite/a-commerce/modules/commerce-catalog/test/skuPresentation.test.ts +53 -4
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +148 -148
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAdjust.tsx +37 -3
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +2 -2
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +7 -6
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +1 -1
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +7 -6
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +10 -7
- package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +4 -4
- package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +39 -67
- package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +56 -37
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +5 -5
- package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +1 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/package.json +6 -1
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/component/tableCellActionAdjustStock.ts +34 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +81 -6
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeStockBalance.ts +32 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +44 -44
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +356 -338
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeStockBalance.ts +17 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/bean/tableCell.actionAdjustStock.tsx +35 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/component/tableCellActionAdjustStock/controller.tsx +138 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +3 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +3 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/stockBalance.ts +36 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +4 -4
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +8 -8
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +11 -11
- package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +2 -2
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/bean/behavior.appModal.tsx +2 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +2 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/test/model/resource.types.ts +11 -0
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-form/src/lib/formLayout.ts +58 -9
- package/zova/src/suite-vendor/a-zova/modules/a-form/test/lib/formLayout.test.ts +157 -0
- package/zova/src/suite-vendor/a-zova/modules/a-model/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.persister.ts +3 -1
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useQuery.ts +11 -13
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useState.ts +9 -7
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useStateGeneral.ts +5 -12
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/lib/queryPersister.ts +17 -0
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/lib/queryRefetch.ts +34 -0
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/types/query.ts +27 -3
- package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/queryPersister.test.ts +115 -0
- package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/queryRefetch.test.ts +84 -0
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts +27 -5
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +4 -0
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/schema.ts +2 -5
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/test/lib/schema.test.ts +179 -0
- package/zova/src/suite-vendor/a-zova/package.json +4 -4
|
@@ -357,114 +357,6 @@ declare module 'vona-module-a-orm' {
|
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
359
|
/** model: end */
|
|
360
|
-
/** service: begin */
|
|
361
|
-
export * from '../service/category.ts';
|
|
362
|
-
export * from '../service/product.ts';
|
|
363
|
-
export * from '../service/sku.ts';
|
|
364
|
-
|
|
365
|
-
import 'vona-module-a-bean';
|
|
366
|
-
declare module 'vona-module-a-bean' {
|
|
367
|
-
|
|
368
|
-
export interface IServiceRecord {
|
|
369
|
-
'commerce-catalog:category': never;
|
|
370
|
-
'commerce-catalog:product': never;
|
|
371
|
-
'commerce-catalog:sku': never;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
declare module 'vona-module-commerce-catalog' {
|
|
377
|
-
|
|
378
|
-
export interface ServiceCategory {
|
|
379
|
-
/** @internal */
|
|
380
|
-
get scope(): ScopeModuleCommerceCatalog;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export interface ServiceCategory {
|
|
384
|
-
get $beanFullName(): 'commerce-catalog.service.category';
|
|
385
|
-
get $onionName(): 'commerce-catalog:category';
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
export interface ServiceProduct {
|
|
389
|
-
/** @internal */
|
|
390
|
-
get scope(): ScopeModuleCommerceCatalog;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
export interface ServiceProduct {
|
|
394
|
-
get $beanFullName(): 'commerce-catalog.service.product';
|
|
395
|
-
get $onionName(): 'commerce-catalog:product';
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
export interface ServiceSku {
|
|
399
|
-
/** @internal */
|
|
400
|
-
get scope(): ScopeModuleCommerceCatalog;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
export interface ServiceSku {
|
|
404
|
-
get $beanFullName(): 'commerce-catalog.service.sku';
|
|
405
|
-
get $onionName(): 'commerce-catalog:sku';
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
/** service: end */
|
|
409
|
-
/** service: begin */
|
|
410
|
-
import type { ServiceCategory } from '../service/category.ts';
|
|
411
|
-
import type { ServiceProduct } from '../service/product.ts';
|
|
412
|
-
import type { ServiceSku } from '../service/sku.ts';
|
|
413
|
-
export interface IModuleService {
|
|
414
|
-
'category': ServiceCategory;
|
|
415
|
-
'product': ServiceProduct;
|
|
416
|
-
'sku': ServiceSku;
|
|
417
|
-
}
|
|
418
|
-
/** service: end */
|
|
419
|
-
/** service: begin */
|
|
420
|
-
|
|
421
|
-
import 'vona';
|
|
422
|
-
declare module 'vona' {
|
|
423
|
-
export interface IBeanRecordGeneral {
|
|
424
|
-
'commerce-catalog.service.category': ServiceCategory;
|
|
425
|
-
'commerce-catalog.service.product': ServiceProduct;
|
|
426
|
-
'commerce-catalog.service.sku': ServiceSku;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
/** service: end */
|
|
430
|
-
/** meta: begin */
|
|
431
|
-
export * from '../bean/meta.index.ts';
|
|
432
|
-
export * from '../bean/meta.version.ts';
|
|
433
|
-
import type { IMetaOptionsIndex } from 'vona-module-a-index';
|
|
434
|
-
import 'vona-module-a-meta';
|
|
435
|
-
declare module 'vona-module-a-meta' {
|
|
436
|
-
|
|
437
|
-
export interface IMetaRecord {
|
|
438
|
-
'commerce-catalog:index': IMetaOptionsIndex;
|
|
439
|
-
'commerce-catalog:version': never;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
declare module 'vona-module-commerce-catalog' {
|
|
445
|
-
|
|
446
|
-
export interface MetaIndex {
|
|
447
|
-
/** @internal */
|
|
448
|
-
get scope(): ScopeModuleCommerceCatalog;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
export interface MetaIndex {
|
|
452
|
-
get $beanFullName(): 'commerce-catalog.meta.index';
|
|
453
|
-
get $onionName(): 'commerce-catalog:index';
|
|
454
|
-
get $onionOptions(): IMetaOptionsIndex;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
export interface MetaVersion {
|
|
458
|
-
/** @internal */
|
|
459
|
-
get scope(): ScopeModuleCommerceCatalog;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
export interface MetaVersion {
|
|
463
|
-
get $beanFullName(): 'commerce-catalog.meta.version';
|
|
464
|
-
get $onionName(): 'commerce-catalog:version';
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
/** meta: end */
|
|
468
360
|
/** dto: begin */
|
|
469
361
|
export * from '../dto/categoryCreate.tsx';
|
|
470
362
|
export * from '../dto/categorySelectReq.tsx';
|
|
@@ -803,6 +695,114 @@ import 'vona-module-a-openapi';
|
|
|
803
695
|
}
|
|
804
696
|
|
|
805
697
|
/** controller: end */
|
|
698
|
+
/** service: begin */
|
|
699
|
+
export * from '../service/category.ts';
|
|
700
|
+
export * from '../service/product.ts';
|
|
701
|
+
export * from '../service/sku.ts';
|
|
702
|
+
|
|
703
|
+
import 'vona-module-a-bean';
|
|
704
|
+
declare module 'vona-module-a-bean' {
|
|
705
|
+
|
|
706
|
+
export interface IServiceRecord {
|
|
707
|
+
'commerce-catalog:category': never;
|
|
708
|
+
'commerce-catalog:product': never;
|
|
709
|
+
'commerce-catalog:sku': never;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
}
|
|
714
|
+
declare module 'vona-module-commerce-catalog' {
|
|
715
|
+
|
|
716
|
+
export interface ServiceCategory {
|
|
717
|
+
/** @internal */
|
|
718
|
+
get scope(): ScopeModuleCommerceCatalog;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
export interface ServiceCategory {
|
|
722
|
+
get $beanFullName(): 'commerce-catalog.service.category';
|
|
723
|
+
get $onionName(): 'commerce-catalog:category';
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
export interface ServiceProduct {
|
|
727
|
+
/** @internal */
|
|
728
|
+
get scope(): ScopeModuleCommerceCatalog;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
export interface ServiceProduct {
|
|
732
|
+
get $beanFullName(): 'commerce-catalog.service.product';
|
|
733
|
+
get $onionName(): 'commerce-catalog:product';
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
export interface ServiceSku {
|
|
737
|
+
/** @internal */
|
|
738
|
+
get scope(): ScopeModuleCommerceCatalog;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
export interface ServiceSku {
|
|
742
|
+
get $beanFullName(): 'commerce-catalog.service.sku';
|
|
743
|
+
get $onionName(): 'commerce-catalog:sku';
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
/** service: end */
|
|
747
|
+
/** service: begin */
|
|
748
|
+
import type { ServiceCategory } from '../service/category.ts';
|
|
749
|
+
import type { ServiceProduct } from '../service/product.ts';
|
|
750
|
+
import type { ServiceSku } from '../service/sku.ts';
|
|
751
|
+
export interface IModuleService {
|
|
752
|
+
'category': ServiceCategory;
|
|
753
|
+
'product': ServiceProduct;
|
|
754
|
+
'sku': ServiceSku;
|
|
755
|
+
}
|
|
756
|
+
/** service: end */
|
|
757
|
+
/** service: begin */
|
|
758
|
+
|
|
759
|
+
import 'vona';
|
|
760
|
+
declare module 'vona' {
|
|
761
|
+
export interface IBeanRecordGeneral {
|
|
762
|
+
'commerce-catalog.service.category': ServiceCategory;
|
|
763
|
+
'commerce-catalog.service.product': ServiceProduct;
|
|
764
|
+
'commerce-catalog.service.sku': ServiceSku;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
/** service: end */
|
|
768
|
+
/** meta: begin */
|
|
769
|
+
export * from '../bean/meta.index.ts';
|
|
770
|
+
export * from '../bean/meta.version.ts';
|
|
771
|
+
import type { IMetaOptionsIndex } from 'vona-module-a-index';
|
|
772
|
+
import 'vona-module-a-meta';
|
|
773
|
+
declare module 'vona-module-a-meta' {
|
|
774
|
+
|
|
775
|
+
export interface IMetaRecord {
|
|
776
|
+
'commerce-catalog:index': IMetaOptionsIndex;
|
|
777
|
+
'commerce-catalog:version': never;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
}
|
|
782
|
+
declare module 'vona-module-commerce-catalog' {
|
|
783
|
+
|
|
784
|
+
export interface MetaIndex {
|
|
785
|
+
/** @internal */
|
|
786
|
+
get scope(): ScopeModuleCommerceCatalog;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
export interface MetaIndex {
|
|
790
|
+
get $beanFullName(): 'commerce-catalog.meta.index';
|
|
791
|
+
get $onionName(): 'commerce-catalog:index';
|
|
792
|
+
get $onionOptions(): IMetaOptionsIndex;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
export interface MetaVersion {
|
|
796
|
+
/** @internal */
|
|
797
|
+
get scope(): ScopeModuleCommerceCatalog;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
export interface MetaVersion {
|
|
801
|
+
get $beanFullName(): 'commerce-catalog.meta.version';
|
|
802
|
+
get $onionName(): 'commerce-catalog:version';
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
/** meta: end */
|
|
806
806
|
/** ssrMenu: begin */
|
|
807
807
|
export * from '../bean/ssrMenu.category.ts';
|
|
808
808
|
export * from '../bean/ssrMenu.product.ts';
|
|
@@ -3,6 +3,7 @@ import type { IDecoratorDtoOptions } from 'vona-module-a-web';
|
|
|
3
3
|
import { Api, v } from 'vona-module-a-openapiutils';
|
|
4
4
|
import { $Dto } from 'vona-module-a-orm';
|
|
5
5
|
import { Dto } from 'vona-module-a-web';
|
|
6
|
+
import { z } from 'zod';
|
|
6
7
|
import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
|
|
7
8
|
|
|
8
9
|
import { $locale } from '../.metadata/locales.ts';
|
|
@@ -62,11 +63,22 @@ export class DtoSkuSelectResItem extends $Dto.get(() => ModelSku, {
|
|
|
62
63
|
product: { columns: ['id', 'title'] },
|
|
63
64
|
},
|
|
64
65
|
}) {
|
|
66
|
+
@Api.field(
|
|
67
|
+
v.title($locale('Available')),
|
|
68
|
+
v.required(),
|
|
69
|
+
z.number().int().nonnegative(),
|
|
70
|
+
ZovaRender.order(5),
|
|
71
|
+
)
|
|
72
|
+
available: number;
|
|
73
|
+
|
|
65
74
|
@Api.field(
|
|
66
75
|
v.title($locale('Operations')),
|
|
67
76
|
ZovaRender.order(1, 'max'),
|
|
68
77
|
ZovaRender.cell('basic-table:actionOperationsRow', {
|
|
69
78
|
actions: [
|
|
79
|
+
ZovaRender.tableActionRow('commerce-trade:actionAdjustStock', {
|
|
80
|
+
permission: { actionInherit: 'update' },
|
|
81
|
+
}),
|
|
70
82
|
ZovaRender.tableActionRow('basic-table:actionUpdate'),
|
|
71
83
|
ZovaRender.tableActionRow('basic-table:actionDelete'),
|
|
72
84
|
],
|
|
@@ -28,13 +28,31 @@ export class ServiceSku extends BeanBase {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
async select(params?: IQueryParams<ModelSku>): Promise<DtoSkuSelectRes> {
|
|
31
|
-
|
|
31
|
+
const result = await this.scope.model.sku.selectAndCount({
|
|
32
32
|
...params,
|
|
33
33
|
include: {
|
|
34
34
|
...params?.include,
|
|
35
35
|
product: { columns: ['id', 'title'] },
|
|
36
36
|
},
|
|
37
37
|
});
|
|
38
|
+
if (result.list.length === 0) return result as unknown as DtoSkuSelectRes;
|
|
39
|
+
|
|
40
|
+
const balances = await this.$scope.commerceTrade.model.stockBalance.select({
|
|
41
|
+
columns: ['skuId', 'available'],
|
|
42
|
+
where: {
|
|
43
|
+
skuId: result.list.map(sku => sku.id),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
const availableBySkuId = new Map(
|
|
47
|
+
balances.map(balance => [String(balance.skuId), balance.available]),
|
|
48
|
+
);
|
|
49
|
+
return {
|
|
50
|
+
...result,
|
|
51
|
+
list: result.list.map(sku => ({
|
|
52
|
+
...sku,
|
|
53
|
+
available: availableBySkuId.get(String(sku.id)) ?? 0,
|
|
54
|
+
})),
|
|
55
|
+
} as DtoSkuSelectRes;
|
|
38
56
|
}
|
|
39
57
|
|
|
40
58
|
async view(id: TableIdentity): Promise<DtoSkuView | undefined> {
|
|
@@ -178,12 +178,21 @@ describe('skuPresentation.test.ts', () => {
|
|
|
178
178
|
listComponent.properties.productId.rest?.table?.columnProps,
|
|
179
179
|
productPickerOptions,
|
|
180
180
|
);
|
|
181
|
+
assert.equal(listComponent.properties.available.rest?.table?.order, undefined);
|
|
182
|
+
assert.equal(listComponent.properties.available.rest?.table?.render, undefined);
|
|
183
|
+
assert.equal(listComponent.properties.available.type, 'integer');
|
|
184
|
+
assert.equal(listComponent.properties.available.minimum, 0);
|
|
185
|
+
assert.equal(listComponent.properties.available.title.toJSON(), 'Available');
|
|
186
|
+
const actions = listComponent.properties._operationsRow.rest.table.columnProps.actions;
|
|
181
187
|
assert.deepEqual(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
188
|
+
actions.map((action: any) => action.render),
|
|
189
|
+
[
|
|
190
|
+
'commerce-trade:actionAdjustStock',
|
|
191
|
+
'basic-table:actionUpdate',
|
|
192
|
+
'basic-table:actionDelete',
|
|
193
|
+
],
|
|
186
194
|
);
|
|
195
|
+
assert.deepEqual(actions[0].options.permission, { actionInherit: 'update' });
|
|
187
196
|
|
|
188
197
|
const filterBlock = listComponent.rest.blocks[0].options.blocks[0];
|
|
189
198
|
const filterLayout = filterBlock.options.blocks[0].options.formLayout;
|
|
@@ -204,6 +213,7 @@ describe('skuPresentation.test.ts', () => {
|
|
|
204
213
|
let categoryId: number | string | undefined;
|
|
205
214
|
let productId: number | string | undefined;
|
|
206
215
|
let skuId: number | string | undefined;
|
|
216
|
+
let skuIdWithBalance: number | string | undefined;
|
|
207
217
|
await app.bean.passport.signinMock();
|
|
208
218
|
try {
|
|
209
219
|
categoryId = await app.bean.executor.performAction('post', '/commerce/catalog/category', {
|
|
@@ -224,6 +234,26 @@ describe('skuPresentation.test.ts', () => {
|
|
|
224
234
|
lifecycle: 'draft',
|
|
225
235
|
},
|
|
226
236
|
});
|
|
237
|
+
const skuIdWithBalance = await app.bean.executor.performAction(
|
|
238
|
+
'post',
|
|
239
|
+
'/commerce/catalog/sku',
|
|
240
|
+
{
|
|
241
|
+
body: {
|
|
242
|
+
code: `presentation-sku-balance-${suffix}`,
|
|
243
|
+
productId,
|
|
244
|
+
priceCents: 2345,
|
|
245
|
+
lifecycle: 'draft',
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
);
|
|
249
|
+
await app.bean.executor.performAction('post', '/commerce/trade/stockBalance/adjustStock', {
|
|
250
|
+
body: {
|
|
251
|
+
skuId: skuIdWithBalance,
|
|
252
|
+
delta: 7,
|
|
253
|
+
reason: `presentation stock ${suffix}`,
|
|
254
|
+
correlationId: `presentation-${suffix}`,
|
|
255
|
+
},
|
|
256
|
+
});
|
|
227
257
|
|
|
228
258
|
const view: any = await app.bean.executor.performAction(
|
|
229
259
|
'get',
|
|
@@ -247,12 +277,31 @@ describe('skuPresentation.test.ts', () => {
|
|
|
247
277
|
});
|
|
248
278
|
assert.equal(select.list.length, 1);
|
|
249
279
|
assert.equal(String(select.list[0].id), String(skuId));
|
|
280
|
+
assert.equal(select.list[0].available, 0);
|
|
250
281
|
assert.deepEqual(select.list[0].product, {
|
|
251
282
|
id: productId,
|
|
252
283
|
title: `presentation-sku-product-${suffix}`,
|
|
253
284
|
});
|
|
254
285
|
assert.equal(select.list[0].attributes, undefined);
|
|
286
|
+
|
|
287
|
+
const balanceSelect: any = await app.bean.executor.performAction(
|
|
288
|
+
'get',
|
|
289
|
+
'/commerce/catalog/sku',
|
|
290
|
+
{ query: { code: `presentation-sku-balance-${suffix}` } },
|
|
291
|
+
);
|
|
292
|
+
assert.equal(balanceSelect.list.length, 1);
|
|
293
|
+
assert.equal(String(balanceSelect.list[0].id), String(skuIdWithBalance));
|
|
294
|
+
assert.equal(balanceSelect.list[0].available, 7);
|
|
255
295
|
} finally {
|
|
296
|
+
const tradeScope = app.scope('commerce-trade');
|
|
297
|
+
if (skuIdWithBalance) {
|
|
298
|
+
await tradeScope.model.stockAudit.delete({ skuId: skuIdWithBalance });
|
|
299
|
+
await tradeScope.model.stockReservation.delete({ skuId: skuIdWithBalance });
|
|
300
|
+
await tradeScope.model.stockBalance.delete({ skuId: skuIdWithBalance });
|
|
301
|
+
await app.bean.executor.performAction('delete', '/commerce/catalog/sku/:id', {
|
|
302
|
+
params: { id: skuIdWithBalance },
|
|
303
|
+
});
|
|
304
|
+
}
|
|
256
305
|
if (skuId) {
|
|
257
306
|
await app.bean.executor.performAction('delete', '/commerce/catalog/sku/:id', {
|
|
258
307
|
params: { id: skuId },
|
|
@@ -675,154 +675,6 @@ declare module 'vona-module-a-orm' {
|
|
|
675
675
|
}
|
|
676
676
|
}
|
|
677
677
|
/** model: end */
|
|
678
|
-
/** bean: begin */
|
|
679
|
-
export * from '../bean/bean.scheduleOrderExpiry.ts';
|
|
680
|
-
|
|
681
|
-
import 'vona';
|
|
682
|
-
declare module 'vona' {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
}
|
|
686
|
-
declare module 'vona-module-commerce-trade' {
|
|
687
|
-
|
|
688
|
-
export interface BeanScheduleOrderExpiry {
|
|
689
|
-
/** @internal */
|
|
690
|
-
get scope(): ScopeModuleCommerceTrade;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
/** bean: end */
|
|
694
|
-
/** bean: begin */
|
|
695
|
-
import type { BeanScheduleOrderExpiry } from '../bean/bean.scheduleOrderExpiry.ts';
|
|
696
|
-
import 'vona';
|
|
697
|
-
declare module 'vona' {
|
|
698
|
-
export interface IBeanRecordGlobal {
|
|
699
|
-
'scheduleOrderExpiry': BeanScheduleOrderExpiry;
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
/** bean: end */
|
|
703
|
-
/** service: begin */
|
|
704
|
-
export * from '../service/cart.ts';
|
|
705
|
-
export * from '../service/order.ts';
|
|
706
|
-
export * from '../service/stockAudit.ts';
|
|
707
|
-
export * from '../service/stockBalance.ts';
|
|
708
|
-
|
|
709
|
-
import 'vona-module-a-bean';
|
|
710
|
-
declare module 'vona-module-a-bean' {
|
|
711
|
-
|
|
712
|
-
export interface IServiceRecord {
|
|
713
|
-
'commerce-trade:cart': never;
|
|
714
|
-
'commerce-trade:order': never;
|
|
715
|
-
'commerce-trade:stockAudit': never;
|
|
716
|
-
'commerce-trade:stockBalance': never;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}
|
|
721
|
-
declare module 'vona-module-commerce-trade' {
|
|
722
|
-
|
|
723
|
-
export interface ServiceCart {
|
|
724
|
-
/** @internal */
|
|
725
|
-
get scope(): ScopeModuleCommerceTrade;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
export interface ServiceCart {
|
|
729
|
-
get $beanFullName(): 'commerce-trade.service.cart';
|
|
730
|
-
get $onionName(): 'commerce-trade:cart';
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
export interface ServiceOrder {
|
|
734
|
-
/** @internal */
|
|
735
|
-
get scope(): ScopeModuleCommerceTrade;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
export interface ServiceOrder {
|
|
739
|
-
get $beanFullName(): 'commerce-trade.service.order';
|
|
740
|
-
get $onionName(): 'commerce-trade:order';
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
export interface ServiceStockAudit {
|
|
744
|
-
/** @internal */
|
|
745
|
-
get scope(): ScopeModuleCommerceTrade;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
export interface ServiceStockAudit {
|
|
749
|
-
get $beanFullName(): 'commerce-trade.service.stockAudit';
|
|
750
|
-
get $onionName(): 'commerce-trade:stockAudit';
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
export interface ServiceStockBalance {
|
|
754
|
-
/** @internal */
|
|
755
|
-
get scope(): ScopeModuleCommerceTrade;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
export interface ServiceStockBalance {
|
|
759
|
-
get $beanFullName(): 'commerce-trade.service.stockBalance';
|
|
760
|
-
get $onionName(): 'commerce-trade:stockBalance';
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
/** service: end */
|
|
764
|
-
/** service: begin */
|
|
765
|
-
import type { ServiceCart } from '../service/cart.ts';
|
|
766
|
-
import type { ServiceOrder } from '../service/order.ts';
|
|
767
|
-
import type { ServiceStockAudit } from '../service/stockAudit.ts';
|
|
768
|
-
import type { ServiceStockBalance } from '../service/stockBalance.ts';
|
|
769
|
-
export interface IModuleService {
|
|
770
|
-
'cart': ServiceCart;
|
|
771
|
-
'order': ServiceOrder;
|
|
772
|
-
'stockAudit': ServiceStockAudit;
|
|
773
|
-
'stockBalance': ServiceStockBalance;
|
|
774
|
-
}
|
|
775
|
-
/** service: end */
|
|
776
|
-
/** service: begin */
|
|
777
|
-
|
|
778
|
-
import 'vona';
|
|
779
|
-
declare module 'vona' {
|
|
780
|
-
export interface IBeanRecordGeneral {
|
|
781
|
-
'commerce-trade.service.cart': ServiceCart;
|
|
782
|
-
'commerce-trade.service.order': ServiceOrder;
|
|
783
|
-
'commerce-trade.service.stockAudit': ServiceStockAudit;
|
|
784
|
-
'commerce-trade.service.stockBalance': ServiceStockBalance;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
/** service: end */
|
|
788
|
-
/** meta: begin */
|
|
789
|
-
export * from '../bean/meta.index.ts';
|
|
790
|
-
export * from '../bean/meta.version.ts';
|
|
791
|
-
import type { IMetaOptionsIndex } from 'vona-module-a-index';
|
|
792
|
-
import 'vona-module-a-meta';
|
|
793
|
-
declare module 'vona-module-a-meta' {
|
|
794
|
-
|
|
795
|
-
export interface IMetaRecord {
|
|
796
|
-
'commerce-trade:index': IMetaOptionsIndex;
|
|
797
|
-
'commerce-trade:version': never;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
}
|
|
802
|
-
declare module 'vona-module-commerce-trade' {
|
|
803
|
-
|
|
804
|
-
export interface MetaIndex {
|
|
805
|
-
/** @internal */
|
|
806
|
-
get scope(): ScopeModuleCommerceTrade;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
export interface MetaIndex {
|
|
810
|
-
get $beanFullName(): 'commerce-trade.meta.index';
|
|
811
|
-
get $onionName(): 'commerce-trade:index';
|
|
812
|
-
get $onionOptions(): IMetaOptionsIndex;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
export interface MetaVersion {
|
|
816
|
-
/** @internal */
|
|
817
|
-
get scope(): ScopeModuleCommerceTrade;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
export interface MetaVersion {
|
|
821
|
-
get $beanFullName(): 'commerce-trade.meta.version';
|
|
822
|
-
get $onionName(): 'commerce-trade:version';
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
/** meta: end */
|
|
826
678
|
/** dto: begin */
|
|
827
679
|
export * from '../dto/cartAddItem.tsx';
|
|
828
680
|
export * from '../dto/cartItem.tsx';
|
|
@@ -1368,6 +1220,154 @@ import 'vona-module-a-openapi';
|
|
|
1368
1220
|
}
|
|
1369
1221
|
|
|
1370
1222
|
/** controller: end */
|
|
1223
|
+
/** bean: begin */
|
|
1224
|
+
export * from '../bean/bean.scheduleOrderExpiry.ts';
|
|
1225
|
+
|
|
1226
|
+
import 'vona';
|
|
1227
|
+
declare module 'vona' {
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
}
|
|
1231
|
+
declare module 'vona-module-commerce-trade' {
|
|
1232
|
+
|
|
1233
|
+
export interface BeanScheduleOrderExpiry {
|
|
1234
|
+
/** @internal */
|
|
1235
|
+
get scope(): ScopeModuleCommerceTrade;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
/** bean: end */
|
|
1239
|
+
/** bean: begin */
|
|
1240
|
+
import type { BeanScheduleOrderExpiry } from '../bean/bean.scheduleOrderExpiry.ts';
|
|
1241
|
+
import 'vona';
|
|
1242
|
+
declare module 'vona' {
|
|
1243
|
+
export interface IBeanRecordGlobal {
|
|
1244
|
+
'scheduleOrderExpiry': BeanScheduleOrderExpiry;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
/** bean: end */
|
|
1248
|
+
/** service: begin */
|
|
1249
|
+
export * from '../service/cart.ts';
|
|
1250
|
+
export * from '../service/order.ts';
|
|
1251
|
+
export * from '../service/stockAudit.ts';
|
|
1252
|
+
export * from '../service/stockBalance.ts';
|
|
1253
|
+
|
|
1254
|
+
import 'vona-module-a-bean';
|
|
1255
|
+
declare module 'vona-module-a-bean' {
|
|
1256
|
+
|
|
1257
|
+
export interface IServiceRecord {
|
|
1258
|
+
'commerce-trade:cart': never;
|
|
1259
|
+
'commerce-trade:order': never;
|
|
1260
|
+
'commerce-trade:stockAudit': never;
|
|
1261
|
+
'commerce-trade:stockBalance': never;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
}
|
|
1266
|
+
declare module 'vona-module-commerce-trade' {
|
|
1267
|
+
|
|
1268
|
+
export interface ServiceCart {
|
|
1269
|
+
/** @internal */
|
|
1270
|
+
get scope(): ScopeModuleCommerceTrade;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
export interface ServiceCart {
|
|
1274
|
+
get $beanFullName(): 'commerce-trade.service.cart';
|
|
1275
|
+
get $onionName(): 'commerce-trade:cart';
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
export interface ServiceOrder {
|
|
1279
|
+
/** @internal */
|
|
1280
|
+
get scope(): ScopeModuleCommerceTrade;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
export interface ServiceOrder {
|
|
1284
|
+
get $beanFullName(): 'commerce-trade.service.order';
|
|
1285
|
+
get $onionName(): 'commerce-trade:order';
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
export interface ServiceStockAudit {
|
|
1289
|
+
/** @internal */
|
|
1290
|
+
get scope(): ScopeModuleCommerceTrade;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
export interface ServiceStockAudit {
|
|
1294
|
+
get $beanFullName(): 'commerce-trade.service.stockAudit';
|
|
1295
|
+
get $onionName(): 'commerce-trade:stockAudit';
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
export interface ServiceStockBalance {
|
|
1299
|
+
/** @internal */
|
|
1300
|
+
get scope(): ScopeModuleCommerceTrade;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
export interface ServiceStockBalance {
|
|
1304
|
+
get $beanFullName(): 'commerce-trade.service.stockBalance';
|
|
1305
|
+
get $onionName(): 'commerce-trade:stockBalance';
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
/** service: end */
|
|
1309
|
+
/** service: begin */
|
|
1310
|
+
import type { ServiceCart } from '../service/cart.ts';
|
|
1311
|
+
import type { ServiceOrder } from '../service/order.ts';
|
|
1312
|
+
import type { ServiceStockAudit } from '../service/stockAudit.ts';
|
|
1313
|
+
import type { ServiceStockBalance } from '../service/stockBalance.ts';
|
|
1314
|
+
export interface IModuleService {
|
|
1315
|
+
'cart': ServiceCart;
|
|
1316
|
+
'order': ServiceOrder;
|
|
1317
|
+
'stockAudit': ServiceStockAudit;
|
|
1318
|
+
'stockBalance': ServiceStockBalance;
|
|
1319
|
+
}
|
|
1320
|
+
/** service: end */
|
|
1321
|
+
/** service: begin */
|
|
1322
|
+
|
|
1323
|
+
import 'vona';
|
|
1324
|
+
declare module 'vona' {
|
|
1325
|
+
export interface IBeanRecordGeneral {
|
|
1326
|
+
'commerce-trade.service.cart': ServiceCart;
|
|
1327
|
+
'commerce-trade.service.order': ServiceOrder;
|
|
1328
|
+
'commerce-trade.service.stockAudit': ServiceStockAudit;
|
|
1329
|
+
'commerce-trade.service.stockBalance': ServiceStockBalance;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
/** service: end */
|
|
1333
|
+
/** meta: begin */
|
|
1334
|
+
export * from '../bean/meta.index.ts';
|
|
1335
|
+
export * from '../bean/meta.version.ts';
|
|
1336
|
+
import type { IMetaOptionsIndex } from 'vona-module-a-index';
|
|
1337
|
+
import 'vona-module-a-meta';
|
|
1338
|
+
declare module 'vona-module-a-meta' {
|
|
1339
|
+
|
|
1340
|
+
export interface IMetaRecord {
|
|
1341
|
+
'commerce-trade:index': IMetaOptionsIndex;
|
|
1342
|
+
'commerce-trade:version': never;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
}
|
|
1347
|
+
declare module 'vona-module-commerce-trade' {
|
|
1348
|
+
|
|
1349
|
+
export interface MetaIndex {
|
|
1350
|
+
/** @internal */
|
|
1351
|
+
get scope(): ScopeModuleCommerceTrade;
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
export interface MetaIndex {
|
|
1355
|
+
get $beanFullName(): 'commerce-trade.meta.index';
|
|
1356
|
+
get $onionName(): 'commerce-trade:index';
|
|
1357
|
+
get $onionOptions(): IMetaOptionsIndex;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
export interface MetaVersion {
|
|
1361
|
+
/** @internal */
|
|
1362
|
+
get scope(): ScopeModuleCommerceTrade;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
export interface MetaVersion {
|
|
1366
|
+
get $beanFullName(): 'commerce-trade.meta.version';
|
|
1367
|
+
get $onionName(): 'commerce-trade:version';
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
/** meta: end */
|
|
1371
1371
|
/** ssrMenu: begin */
|
|
1372
1372
|
export * from '../bean/ssrMenu.order.ts';
|
|
1373
1373
|
export * from '../bean/ssrMenu.stockAudit.ts';
|