@things-factory/sales 10.1.212 → 10.1.214

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.
@@ -7,6 +7,8 @@ tslib_1.__exportStar(require("./service"), exports);
7
7
  require("./routes");
8
8
  const auth_base_1 = require("@things-factory/auth-base");
9
9
  const role_tasks_1 = require("./role-tasks");
10
+ const sales_read_1 = require("./service/sales-read");
10
11
  for (const task of role_tasks_1.ROLE_TASKS)
11
12
  (0, auth_base_1.registerRoleTask)(task);
13
+ (0, sales_read_1.registerSalesReads)();
12
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,uDAA4B;AAC5B,wDAA6B;AAC7B,oDAAyB;AAEzB,oBAAiB;AAEjB,yDAA4D;AAC5D,6CAAyC;AAEzC,KAAK,MAAM,IAAI,IAAI,uBAAU;IAAE,IAAA,4BAAgB,EAAC,IAAI,CAAC,CAAA","sourcesContent":["export * from './migrations'\nexport * from './middlewares'\nexport * from './service'\n\nimport './routes'\n\nimport { registerRoleTask } from '@things-factory/auth-base'\nimport { ROLE_TASKS } from './role-tasks'\n\nfor (const task of ROLE_TASKS) registerRoleTask(task)\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,uDAA4B;AAC5B,wDAA6B;AAC7B,oDAAyB;AAEzB,oBAAiB;AAEjB,yDAA4D;AAC5D,6CAAyC;AACzC,qDAAyD;AAEzD,KAAK,MAAM,IAAI,IAAI,uBAAU;IAAE,IAAA,4BAAgB,EAAC,IAAI,CAAC,CAAA;AACrD,IAAA,+BAAkB,GAAE,CAAA","sourcesContent":["export * from './migrations'\nexport * from './middlewares'\nexport * from './service'\n\nimport './routes'\n\nimport { registerRoleTask } from '@things-factory/auth-base'\nimport { ROLE_TASKS } from './role-tasks'\nimport { registerSalesReads } from './service/sales-read'\n\nfor (const task of ROLE_TASKS) registerRoleTask(task)\nregisterSalesReads()\n"]}
@@ -9,6 +9,7 @@ export * from './opportunity/opportunity-event';
9
9
  export * from './opportunity/opportunity-rules';
10
10
  export * from './opportunity/opportunity-service';
11
11
  export * from './opportunity/opportunity-type';
12
+ export * from './sales-read';
12
13
  export declare const entities: (typeof import("./opportunity/opportunity").Opportunity | typeof import("./quotation/quotation-item").QuotationItem | typeof import("./quotation/quotation").Quotation | typeof import("./quotation/quotation-event").QuotationEvent | typeof import("./opportunity/opportunity-event").OpportunityEvent)[];
13
14
  export declare const subscribers: any[];
14
15
  export declare const schema: {
@@ -13,6 +13,7 @@ tslib_1.__exportStar(require("./opportunity/opportunity-event"), exports);
13
13
  tslib_1.__exportStar(require("./opportunity/opportunity-rules"), exports);
14
14
  tslib_1.__exportStar(require("./opportunity/opportunity-service"), exports);
15
15
  tslib_1.__exportStar(require("./opportunity/opportunity-type"), exports);
16
+ tslib_1.__exportStar(require("./sales-read"), exports);
16
17
  const opportunity = tslib_1.__importStar(require("./opportunity"));
17
18
  const quotation = tslib_1.__importStar(require("./quotation"));
18
19
  exports.entities = [...quotation.entities, ...opportunity.entities];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,gEAAqC;AACrC,qEAA0C;AAC1C,sEAA2C;AAC3C,sEAA2C;AAC3C,wEAA6C;AAC7C,qEAA0C;AAC1C,oEAAyC;AACzC,0EAA+C;AAC/C,0EAA+C;AAC/C,4EAAiD;AACjD,yEAA8C;AAE9C,mEAA4C;AAC5C,+DAAwC;AAE3B,QAAA,QAAQ,GAAG,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAC3D,QAAA,WAAW,GAAG,CAAC,GAAG,SAAS,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC,WAAW,CAAC,CAAA;AACpE,QAAA,MAAM,GAAG,EAAE,eAAe,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,GAAG,WAAW,CAAC,SAAS,CAAC,EAAE,CAAA","sourcesContent":["export * from './quotation/quotation'\nexport * from './quotation/quotation-item'\nexport * from './quotation/quotation-event'\nexport * from './quotation/quotation-rules'\nexport * from './quotation/quotation-service'\nexport * from './quotation/quotation-type'\nexport * from './opportunity/opportunity'\nexport * from './opportunity/opportunity-event'\nexport * from './opportunity/opportunity-rules'\nexport * from './opportunity/opportunity-service'\nexport * from './opportunity/opportunity-type'\n\nimport * as opportunity from './opportunity'\nimport * as quotation from './quotation'\n\nexport const entities = [...quotation.entities, ...opportunity.entities]\nexport const subscribers = [...quotation.subscribers, ...opportunity.subscribers]\nexport const schema = { resolverClasses: [...quotation.resolvers, ...opportunity.resolvers] }\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,gEAAqC;AACrC,qEAA0C;AAC1C,sEAA2C;AAC3C,sEAA2C;AAC3C,wEAA6C;AAC7C,qEAA0C;AAC1C,oEAAyC;AACzC,0EAA+C;AAC/C,0EAA+C;AAC/C,4EAAiD;AACjD,yEAA8C;AAC9C,uDAA4B;AAE5B,mEAA4C;AAC5C,+DAAwC;AAE3B,QAAA,QAAQ,GAAG,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAC3D,QAAA,WAAW,GAAG,CAAC,GAAG,SAAS,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC,WAAW,CAAC,CAAA;AACpE,QAAA,MAAM,GAAG,EAAE,eAAe,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,GAAG,WAAW,CAAC,SAAS,CAAC,EAAE,CAAA","sourcesContent":["export * from './quotation/quotation'\nexport * from './quotation/quotation-item'\nexport * from './quotation/quotation-event'\nexport * from './quotation/quotation-rules'\nexport * from './quotation/quotation-service'\nexport * from './quotation/quotation-type'\nexport * from './opportunity/opportunity'\nexport * from './opportunity/opportunity-event'\nexport * from './opportunity/opportunity-rules'\nexport * from './opportunity/opportunity-service'\nexport * from './opportunity/opportunity-type'\nexport * from './sales-read'\n\nimport * as opportunity from './opportunity'\nimport * as quotation from './quotation'\n\nexport const entities = [...quotation.entities, ...opportunity.entities]\nexport const subscribers = [...quotation.subscribers, ...opportunity.subscribers]\nexport const schema = { resolverClasses: [...quotation.resolvers, ...opportunity.resolvers] }\n"]}
@@ -0,0 +1,8 @@
1
+ export declare enum QuotationStatus {
2
+ DRAFT = "DRAFT",
3
+ SENT = "SENT",
4
+ ACCEPTED = "ACCEPTED",
5
+ REJECTED = "REJECTED",
6
+ EXPIRED = "EXPIRED",
7
+ SUPERSEDED = "SUPERSEDED"
8
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuotationStatus = void 0;
4
+ const type_graphql_1 = require("type-graphql");
5
+ /* Apart from the entity, so what reads the statuses (the assistant's list read, its test) needs no type-graphql class. */
6
+ var QuotationStatus;
7
+ (function (QuotationStatus) {
8
+ QuotationStatus["DRAFT"] = "DRAFT";
9
+ QuotationStatus["SENT"] = "SENT";
10
+ QuotationStatus["ACCEPTED"] = "ACCEPTED";
11
+ QuotationStatus["REJECTED"] = "REJECTED";
12
+ QuotationStatus["EXPIRED"] = "EXPIRED";
13
+ QuotationStatus["SUPERSEDED"] = "SUPERSEDED";
14
+ })(QuotationStatus || (exports.QuotationStatus = QuotationStatus = {}));
15
+ (0, type_graphql_1.registerEnumType)(QuotationStatus, {
16
+ name: 'QuotationStatus',
17
+ description: 'state of a quotation — draft, sent, accepted, rejected, expired, or replaced by a revision'
18
+ });
19
+ //# sourceMappingURL=quotation-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quotation-status.js","sourceRoot":"","sources":["../../../server/service/quotation/quotation-status.ts"],"names":[],"mappings":";;;AAAA,+CAA+C;AAE/C,0HAA0H;AAC1H,IAAY,eAOX;AAPD,WAAY,eAAe;IACzB,kCAAe,CAAA;IACf,gCAAa,CAAA;IACb,wCAAqB,CAAA;IACrB,wCAAqB,CAAA;IACrB,sCAAmB,CAAA;IACnB,4CAAyB,CAAA;AAC3B,CAAC,EAPW,eAAe,+BAAf,eAAe,QAO1B;AACD,IAAA,+BAAgB,EAAC,eAAe,EAAE;IAChC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,4FAA4F;CAC1G,CAAC,CAAA","sourcesContent":["import { registerEnumType } from 'type-graphql'\n\n/* Apart from the entity, so what reads the statuses (the assistant's list read, its test) needs no type-graphql class. */\nexport enum QuotationStatus {\n DRAFT = 'DRAFT',\n SENT = 'SENT',\n ACCEPTED = 'ACCEPTED',\n REJECTED = 'REJECTED',\n EXPIRED = 'EXPIRED',\n SUPERSEDED = 'SUPERSEDED'\n}\nregisterEnumType(QuotationStatus, {\n name: 'QuotationStatus',\n description: 'state of a quotation — draft, sent, accepted, rejected, expired, or replaced by a revision'\n})\n"]}
@@ -3,14 +3,8 @@ import { CommercialDocument } from '@things-factory/invoice';
3
3
  import { Domain } from '@things-factory/shell';
4
4
  import { Opportunity } from '../opportunity/opportunity';
5
5
  import { QuotationItem } from './quotation-item';
6
- export declare enum QuotationStatus {
7
- DRAFT = "DRAFT",
8
- SENT = "SENT",
9
- ACCEPTED = "ACCEPTED",
10
- REJECTED = "REJECTED",
11
- EXPIRED = "EXPIRED",
12
- SUPERSEDED = "SUPERSEDED"
13
- }
6
+ import { QuotationStatus } from './quotation-status';
7
+ export { QuotationStatus };
14
8
  /**
15
9
  * A quotation — the same printed head and lines as an invoice, valid until a day. A sent quotation is changed by
16
10
  * revising it: the revision keeps the number and takes the next version, and the one before is superseded.
@@ -9,19 +9,8 @@ const type_graphql_1 = require("type-graphql");
9
9
  const typeorm_1 = require("typeorm");
10
10
  const opportunity_1 = require("../opportunity/opportunity");
11
11
  const quotation_item_1 = require("./quotation-item");
12
- var QuotationStatus;
13
- (function (QuotationStatus) {
14
- QuotationStatus["DRAFT"] = "DRAFT";
15
- QuotationStatus["SENT"] = "SENT";
16
- QuotationStatus["ACCEPTED"] = "ACCEPTED";
17
- QuotationStatus["REJECTED"] = "REJECTED";
18
- QuotationStatus["EXPIRED"] = "EXPIRED";
19
- QuotationStatus["SUPERSEDED"] = "SUPERSEDED";
20
- })(QuotationStatus || (exports.QuotationStatus = QuotationStatus = {}));
21
- (0, type_graphql_1.registerEnumType)(QuotationStatus, {
22
- name: 'QuotationStatus',
23
- description: 'state of a quotation — draft, sent, accepted, rejected, expired, or replaced by a revision'
24
- });
12
+ const quotation_status_1 = require("./quotation-status");
13
+ Object.defineProperty(exports, "QuotationStatus", { enumerable: true, get: function () { return quotation_status_1.QuotationStatus; } });
25
14
  /**
26
15
  * A quotation — the same printed head and lines as an invoice, valid until a day. A sent quotation is changed by
27
16
  * revising it: the revision keeps the number and takes the next version, and the one before is superseded.
@@ -49,8 +38,8 @@ tslib_1.__decorate([
49
38
  tslib_1.__metadata("design:type", Number)
50
39
  ], Quotation.prototype, "version", void 0);
51
40
  tslib_1.__decorate([
52
- (0, typeorm_1.Column)({ default: QuotationStatus.DRAFT }),
53
- (0, type_graphql_1.Field)(type => QuotationStatus, { description: 'Draft, sent, accepted, rejected, expired or superseded' }),
41
+ (0, typeorm_1.Column)({ default: quotation_status_1.QuotationStatus.DRAFT }),
42
+ (0, type_graphql_1.Field)(type => quotation_status_1.QuotationStatus, { description: 'Draft, sent, accepted, rejected, expired or superseded' }),
54
43
  tslib_1.__metadata("design:type", String)
55
44
  ], Quotation.prototype, "status", void 0);
56
45
  tslib_1.__decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"quotation.js","sourceRoot":"","sources":["../../../server/service/quotation/quotation.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '@things-factory/auth-base'\nimport { CommercialDocument } from '@things-factory/invoice'\nimport { Domain } from '@things-factory/shell'\nimport { Field, ID, Int, ObjectType, registerEnumType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { Opportunity } from '../opportunity/opportunity'\nimport { QuotationItem } from './quotation-item'\n\nexport enum QuotationStatus {\n DRAFT = 'DRAFT',\n SENT = 'SENT',\n ACCEPTED = 'ACCEPTED',\n REJECTED = 'REJECTED',\n EXPIRED = 'EXPIRED',\n SUPERSEDED = 'SUPERSEDED'\n}\nregisterEnumType(QuotationStatus, {\n name: 'QuotationStatus',\n description: 'state of a quotation — draft, sent, accepted, rejected, expired, or replaced by a revision'\n})\n\n/**\n * A quotation — the same printed head and lines as an invoice, valid until a day. A sent quotation is changed by\n * revising it: the revision keeps the number and takes the next version, and the one before is superseded.\n */\n@Entity()\n@Index('ix_quotation_0', (quotation: Quotation) => [quotation.domain, quotation.number, quotation.version], { unique: true, where: '\"deleted_at\" IS NULL' })\n@Index('ix_quotation_1', (quotation: Quotation) => [quotation.domain, quotation.status, quotation.validUntil])\n@Index('ix_quotation_2', (quotation: Quotation) => [quotation.domain, quotation.opportunity])\n@ObjectType({ description: 'Entity for Quotation — a priced offer, kept with every revision' })\nexport class Quotation extends CommercialDocument {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true })\n domain?: Domain\n\n @RelationId((quotation: Quotation) => quotation.domain)\n domainId?: string\n\n @Column({ type: 'int', default: 1 })\n @Field(type => Int, { description: 'Revision of the quotation number, from 1' })\n version: number\n\n @Column({ default: QuotationStatus.DRAFT })\n @Field(type => QuotationStatus, { description: 'Draft, sent, accepted, rejected, expired or superseded' })\n status: QuotationStatus\n\n @Column()\n @Field({ description: 'Last day the offer holds, YYYY-MM-DD' })\n validUntil: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Why the buyer declined, when rejected' })\n outcomeReason?: string\n\n /* An opportunity may have several quotations; a quotation answers at most one (ADR-0138 decision 7). */\n @ManyToOne(type => Opportunity, { nullable: true })\n @Field(type => Opportunity, { nullable: true, description: 'The sales opportunity the quotation answers, when there is one' })\n opportunity?: Opportunity\n\n @RelationId((quotation: Quotation) => quotation.opportunity)\n @Field({ nullable: true, description: 'Id of the sales opportunity the quotation answers' })\n opportunityId?: string\n\n @OneToMany(type => QuotationItem, item => item.quotation)\n @Field(type => [QuotationItem], { description: 'Lines in printed order' })\n items: QuotationItem[]\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the quotation was created' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the quotation last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the quotation was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((quotation: Quotation) => quotation.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((quotation: Quotation) => quotation.updater)\n updaterId?: string\n}\n"]}
1
+ {"version":3,"file":"quotation.js","sourceRoot":"","sources":["../../../server/service/quotation/quotation.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '@things-factory/auth-base'\nimport { CommercialDocument } from '@things-factory/invoice'\nimport { Domain } from '@things-factory/shell'\nimport { Field, ID, Int, ObjectType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { Opportunity } from '../opportunity/opportunity'\nimport { QuotationItem } from './quotation-item'\nimport { QuotationStatus } from './quotation-status'\n\nexport { QuotationStatus }\n\n/**\n * A quotation — the same printed head and lines as an invoice, valid until a day. A sent quotation is changed by\n * revising it: the revision keeps the number and takes the next version, and the one before is superseded.\n */\n@Entity()\n@Index('ix_quotation_0', (quotation: Quotation) => [quotation.domain, quotation.number, quotation.version], { unique: true, where: '\"deleted_at\" IS NULL' })\n@Index('ix_quotation_1', (quotation: Quotation) => [quotation.domain, quotation.status, quotation.validUntil])\n@Index('ix_quotation_2', (quotation: Quotation) => [quotation.domain, quotation.opportunity])\n@ObjectType({ description: 'Entity for Quotation — a priced offer, kept with every revision' })\nexport class Quotation extends CommercialDocument {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true })\n domain?: Domain\n\n @RelationId((quotation: Quotation) => quotation.domain)\n domainId?: string\n\n @Column({ type: 'int', default: 1 })\n @Field(type => Int, { description: 'Revision of the quotation number, from 1' })\n version: number\n\n @Column({ default: QuotationStatus.DRAFT })\n @Field(type => QuotationStatus, { description: 'Draft, sent, accepted, rejected, expired or superseded' })\n status: QuotationStatus\n\n @Column()\n @Field({ description: 'Last day the offer holds, YYYY-MM-DD' })\n validUntil: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Why the buyer declined, when rejected' })\n outcomeReason?: string\n\n /* An opportunity may have several quotations; a quotation answers at most one (ADR-0138 decision 7). */\n @ManyToOne(type => Opportunity, { nullable: true })\n @Field(type => Opportunity, { nullable: true, description: 'The sales opportunity the quotation answers, when there is one' })\n opportunity?: Opportunity\n\n @RelationId((quotation: Quotation) => quotation.opportunity)\n @Field({ nullable: true, description: 'Id of the sales opportunity the quotation answers' })\n opportunityId?: string\n\n @OneToMany(type => QuotationItem, item => item.quotation)\n @Field(type => [QuotationItem], { description: 'Lines in printed order' })\n items: QuotationItem[]\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the quotation was created' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the quotation last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the quotation was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((quotation: Quotation) => quotation.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((quotation: Quotation) => quotation.updater)\n updaterId?: string\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import { type ListRead } from '@things-factory/ai-assistant';
2
+ export declare const OPPORTUNITY_LIST_READ: ListRead;
3
+ export declare const QUOTATION_LIST_READ: ListRead;
4
+ /** The keys an application's assistant mode names in its `readTargets` to read opportunities and quotations. */
5
+ export declare const SALES_READ_TARGETS: string[];
6
+ /** At boot: the assistant may read the opportunity and quotation lists, in a mode that names them. */
7
+ export declare function registerSalesReads(): void;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SALES_READ_TARGETS = exports.QUOTATION_LIST_READ = exports.OPPORTUNITY_LIST_READ = void 0;
4
+ exports.registerSalesReads = registerSalesReads;
5
+ const ai_assistant_1 = require("@things-factory/ai-assistant");
6
+ const opportunity_rules_1 = require("./opportunity/opportunity-rules");
7
+ const quotation_status_1 = require("./quotation/quotation-status");
8
+ /*
9
+ * 영업 기회 and 견적 as the assistant reads them (design/ai/read-targets.md §3) - each list screen's own query, as the
10
+ * person: what the sales door lets them see, they read with the assistant. The rows a person picks on a list
11
+ * (「AI와 작업」) go as `opportunity:<uuid>` and `quotation:<uuid>` - each key's last part - and are read here by their
12
+ * ids. The search words are the resolvers' searchables, field for field; a test holds them equal.
13
+ */
14
+ exports.OPPORTUNITY_LIST_READ = {
15
+ key: 'sales.opportunity',
16
+ title: 'title.opportunity-list',
17
+ name: 'Sales opportunities (영업 기회)',
18
+ listQuery: 'opportunities',
19
+ selection: 'id name stage probability amount currency expectedCloseMonth closedOn lostReason description counterparty { id name } endCustomer { id name } owner { id name }',
20
+ columns: [
21
+ { name: 'name', type: 'string', labelKey: 'field.opportunity-name' },
22
+ { name: 'counterparty', path: 'counterparty.name', type: 'string', labelKey: 'field.opportunity-counterparty' },
23
+ { name: 'endCustomer', path: 'endCustomer.name', type: 'string', labelKey: 'field.opportunity-end-customer' },
24
+ { name: 'stage', type: 'string', labelKey: 'field.opportunity-stage' },
25
+ { name: 'probability', type: 'number', labelKey: 'field.opportunity-probability' },
26
+ { name: 'currency', type: 'string' },
27
+ { name: 'amount', type: 'number', total: true, currency: 'currency', labelKey: 'field.opportunity-amount' },
28
+ { name: 'expectedCloseMonth', type: 'string', labelKey: 'field.opportunity-expected-close-month' },
29
+ { name: 'closedOn', type: 'date' },
30
+ { name: 'lostReason', type: 'string' },
31
+ { name: 'owner', path: 'owner.name', type: 'string', labelKey: 'field.opportunity-owner' },
32
+ { name: 'description', type: 'string' }
33
+ ],
34
+ monthField: 'expectedCloseMonth',
35
+ status: { field: 'stage', values: Object.values(opportunity_rules_1.OpportunityStage) },
36
+ search: 'fields name, description',
37
+ route: 'opportunity-list'
38
+ };
39
+ exports.QUOTATION_LIST_READ = {
40
+ key: 'sales.quotation',
41
+ title: 'title.quotation-list',
42
+ name: 'Quotations (견적) - every version of every number',
43
+ listQuery: 'quotations',
44
+ selection: 'id number version status direction currency supplierName buyerName issueDate validUntil purchaseOrder paymentTerms notes outcomeReason opportunityId supplyAmount taxAmount totalAmount',
45
+ columns: [
46
+ { name: 'number', type: 'string', labelKey: 'field.quotation-number' },
47
+ { name: 'version', type: 'number', labelKey: 'field.quotation-version' },
48
+ { name: 'status', type: 'string', labelKey: 'field.quotation-status' },
49
+ { name: 'direction', type: 'string' },
50
+ { name: 'supplierName', type: 'string' },
51
+ { name: 'buyerName', type: 'string' },
52
+ { name: 'issueDate', type: 'date', labelKey: 'field.quotation-issue-date' },
53
+ { name: 'validUntil', type: 'date', labelKey: 'field.quotation-valid-until' },
54
+ { name: 'opportunityId', type: 'string' },
55
+ { name: 'currency', type: 'string' },
56
+ { name: 'supplyAmount', type: 'number', total: true, currency: 'currency' },
57
+ { name: 'taxAmount', type: 'number', total: true, currency: 'currency' },
58
+ { name: 'totalAmount', type: 'number', total: true, currency: 'currency', labelKey: 'field.quotation-total-amount' },
59
+ { name: 'purchaseOrder', type: 'string' },
60
+ { name: 'paymentTerms', type: 'string' },
61
+ { name: 'outcomeReason', type: 'string' },
62
+ { name: 'notes', type: 'string' }
63
+ ],
64
+ dateField: 'issueDate',
65
+ status: { field: 'status', values: Object.values(quotation_status_1.QuotationStatus) },
66
+ search: 'fields number, supplierName, buyerName, notes',
67
+ route: 'quotation-list'
68
+ };
69
+ /** The keys an application's assistant mode names in its `readTargets` to read opportunities and quotations. */
70
+ exports.SALES_READ_TARGETS = [exports.OPPORTUNITY_LIST_READ.key, exports.QUOTATION_LIST_READ.key];
71
+ /** At boot: the assistant may read the opportunity and quotation lists, in a mode that names them. */
72
+ function registerSalesReads() {
73
+ for (const list of [exports.OPPORTUNITY_LIST_READ, exports.QUOTATION_LIST_READ])
74
+ (0, ai_assistant_1.registerReadTarget)((0, ai_assistant_1.listReadTarget)(list));
75
+ }
76
+ //# sourceMappingURL=sales-read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sales-read.js","sourceRoot":"","sources":["../../server/service/sales-read.ts"],"names":[],"mappings":"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","sourcesContent":["import { listReadTarget, registerReadTarget, type ListRead } from '@things-factory/ai-assistant'\n\nimport { OpportunityStage } from './opportunity/opportunity-rules'\nimport { QuotationStatus } from './quotation/quotation-status'\n\n/*\n * 영업 기회 and 견적 as the assistant reads them (design/ai/read-targets.md §3) - each list screen's own query, as the\n * person: what the sales door lets them see, they read with the assistant. The rows a person picks on a list\n * (「AI와 작업」) go as `opportunity:<uuid>` and `quotation:<uuid>` - each key's last part - and are read here by their\n * ids. The search words are the resolvers' searchables, field for field; a test holds them equal.\n */\nexport const OPPORTUNITY_LIST_READ: ListRead = {\n key: 'sales.opportunity',\n title: 'title.opportunity-list',\n name: 'Sales opportunities (영업 기회)',\n listQuery: 'opportunities',\n selection:\n 'id name stage probability amount currency expectedCloseMonth closedOn lostReason description counterparty { id name } endCustomer { id name } owner { id name }',\n columns: [\n { name: 'name', type: 'string', labelKey: 'field.opportunity-name' },\n { name: 'counterparty', path: 'counterparty.name', type: 'string', labelKey: 'field.opportunity-counterparty' },\n { name: 'endCustomer', path: 'endCustomer.name', type: 'string', labelKey: 'field.opportunity-end-customer' },\n { name: 'stage', type: 'string', labelKey: 'field.opportunity-stage' },\n { name: 'probability', type: 'number', labelKey: 'field.opportunity-probability' },\n { name: 'currency', type: 'string' },\n { name: 'amount', type: 'number', total: true, currency: 'currency', labelKey: 'field.opportunity-amount' },\n { name: 'expectedCloseMonth', type: 'string', labelKey: 'field.opportunity-expected-close-month' },\n { name: 'closedOn', type: 'date' },\n { name: 'lostReason', type: 'string' },\n { name: 'owner', path: 'owner.name', type: 'string', labelKey: 'field.opportunity-owner' },\n { name: 'description', type: 'string' }\n ],\n monthField: 'expectedCloseMonth',\n status: { field: 'stage', values: Object.values(OpportunityStage) },\n search: 'fields name, description',\n route: 'opportunity-list'\n}\n\nexport const QUOTATION_LIST_READ: ListRead = {\n key: 'sales.quotation',\n title: 'title.quotation-list',\n name: 'Quotations (견적) - every version of every number',\n listQuery: 'quotations',\n selection:\n 'id number version status direction currency supplierName buyerName issueDate validUntil purchaseOrder paymentTerms notes outcomeReason opportunityId supplyAmount taxAmount totalAmount',\n columns: [\n { name: 'number', type: 'string', labelKey: 'field.quotation-number' },\n { name: 'version', type: 'number', labelKey: 'field.quotation-version' },\n { name: 'status', type: 'string', labelKey: 'field.quotation-status' },\n { name: 'direction', type: 'string' },\n { name: 'supplierName', type: 'string' },\n { name: 'buyerName', type: 'string' },\n { name: 'issueDate', type: 'date', labelKey: 'field.quotation-issue-date' },\n { name: 'validUntil', type: 'date', labelKey: 'field.quotation-valid-until' },\n { name: 'opportunityId', type: 'string' },\n { name: 'currency', type: 'string' },\n { name: 'supplyAmount', type: 'number', total: true, currency: 'currency' },\n { name: 'taxAmount', type: 'number', total: true, currency: 'currency' },\n { name: 'totalAmount', type: 'number', total: true, currency: 'currency', labelKey: 'field.quotation-total-amount' },\n { name: 'purchaseOrder', type: 'string' },\n { name: 'paymentTerms', type: 'string' },\n { name: 'outcomeReason', type: 'string' },\n { name: 'notes', type: 'string' }\n ],\n dateField: 'issueDate',\n status: { field: 'status', values: Object.values(QuotationStatus) },\n search: 'fields number, supplierName, buyerName, notes',\n route: 'quotation-list'\n}\n\n/** The keys an application's assistant mode names in its `readTargets` to read opportunities and quotations. */\nexport const SALES_READ_TARGETS = [OPPORTUNITY_LIST_READ.key, QUOTATION_LIST_READ.key]\n\n/** At boot: the assistant may read the opportunity and quotation lists, in a mode that names them. */\nexport function registerSalesReads(): void {\n for (const list of [OPPORTUNITY_LIST_READ, QUOTATION_LIST_READ]) registerReadTarget(listReadTarget(list))\n}\n"]}