@bisondesk/core-sdk 1.0.634 → 1.0.636

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp.js","sourceRoot":"/","sources":["types/whatsapp.ts"],"names":[],"mappings":"","sourcesContent":["import {\n WhatsappActivityTemplateName,\n WhatsappTemplateTranslation,\n} from '@bisondesk/commons-sdk/notifications-whatsapp';\nimport { BusinessEntityIds } from '../constants.js';\nimport { Activity } from './activities.js';\nimport { DataRecord } from './utils.js';\n\nexport type { WhatsappActivityTemplateName };\n\nexport type WhatsappTemplateLanguage = {\n language: string;\n status: string;\n};\n\nexport type WhatsappTemplateSummary = {\n name: WhatsappActivityTemplateName;\n languages: WhatsappTemplateLanguage[];\n};\n\nexport type WhatsappActivityTemplateTranslation =\n WhatsappTemplateTranslation<WhatsappActivityTemplateName>;\n\nexport type WhatsappTemplatePreview = {\n sent: WhatsappActivityTemplateTranslation;\n canonical?: WhatsappActivityTemplateTranslation;\n};\n\nexport type WhatsappRecipient = {\n contactId?: string;\n organizationId?: string;\n phone: string;\n countryLanguage?: string;\n};\n\nexport type WhatsappActivityContext = {\n businessEntityId: BusinessEntityIds;\n recordId: string;\n organizationId?: string;\n};\n\nexport type SendWhatsappActivityTemplateRequest = {\n templateName: WhatsappActivityTemplateName;\n language: string;\n recipient: Pick<WhatsappRecipient, 'contactId' | 'phone'>;\n context: WhatsappActivityContext;\n};\n\nexport type SendWhatsappActivityTemplateResponse = DataRecord<Activity>;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bisondesk/core-sdk",
3
- "version": "1.0.634",
3
+ "version": "1.0.636",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "author": "TheTruckCompany",
package/src/apis/crm.ts CHANGED
@@ -95,6 +95,27 @@ export const getCrmOrganizationsByVatNumber = async (
95
95
  throw new XError(response.statusText, { url, body, tenantId, vatNumber });
96
96
  };
97
97
 
98
+ export const getCrmOrganizationsByRegistrationNumber = async (
99
+ tenantId: string,
100
+ registrationNumber: string,
101
+ ): Promise<Organization[]> => {
102
+ const auth = await getAdminAuth();
103
+ const url = `${process.env.CORE_API_ORIGIN}/admin/crm/organizations/registration-number/${encodeURIComponent(registrationNumber)}`;
104
+ const response: Response = await fetch(url, {
105
+ headers: cleanHeaders({
106
+ Authorization: auth,
107
+ [TENANT_ID_ADMIN_HEADER]: tenantId,
108
+ }),
109
+ });
110
+
111
+ if (response.ok) {
112
+ return (response.status === 200 ? response.json() : []) as Promise<Organization[]>;
113
+ }
114
+
115
+ const body = await response.text();
116
+ throw new XError(response.statusText, { url, body, tenantId, registrationNumber });
117
+ };
118
+
98
119
  export const saveCrmOrganization = async (
99
120
  tenantId: string,
100
121
  org: Organization | NewOrganization,
@@ -94,8 +94,8 @@ export type ActivityDeleteEvent = BaseActivityEvent & {
94
94
  export type ActivityV2Meta =
95
95
  | EmailDebtorsDossierActivityPayload
96
96
  | CallActivityPayload
97
- | MeetingDebtorsDossierActivityPayload
98
- | ChatDebtorsDossierActivityPayload;
97
+ | MeetingActivityPayload
98
+ | ChatActivityPayload;
99
99
 
100
100
  export type EmailDebtorsDossierActivityPayload = {
101
101
  /* from: { email: string; name?: string; external?: boolean };
@@ -115,7 +115,7 @@ export type CallActivityPayload = {
115
115
  transcription?: string; */
116
116
  };
117
117
 
118
- export type MeetingDebtorsDossierActivityPayload = {
118
+ export type MeetingActivityPayload = {
119
119
  /* organizer: string;
120
120
  participants: string[];
121
121
  location?: string;
@@ -123,9 +123,11 @@ export type MeetingDebtorsDossierActivityPayload = {
123
123
  endTime: string; */
124
124
  };
125
125
 
126
- export type ChatDebtorsDossierActivityPayload = {
126
+ export type ChatActivityPayload = {
127
127
  /* from: { phone: string; name?: string; external?: boolean };
128
128
  to: string[]; */
129
129
  message: string;
130
130
  platform: 'whatsapp' | 'sms';
131
+ templateName?: string;
132
+ language?: string;
131
133
  };
package/src/types/crm.ts CHANGED
@@ -120,6 +120,12 @@ type BaseOrganization = {
120
120
  * cautionnement names the customer by capital alongside its trade-register number.
121
121
  */
122
122
  shareCapital?: string;
123
+ /**
124
+ * National business registration number. For FR orgs this is a SIREN (9 digits) or a SIRET
125
+ * (14 digits = SIREN + 5-digit NIC) — whichever is available; needed for annuaire routing of
126
+ * FR B2B e-invoices. A SIREN is derivable from a valid FR VAT (digits 3–11).
127
+ */
128
+ registrationNumber?: string;
123
129
  addresses?: {
124
130
  legal?: LocationValue;
125
131
  transport?: LocationValue;
@@ -120,6 +120,24 @@ export type SalesReportHistogramBucket = {
120
120
  count: number;
121
121
  };
122
122
 
123
+ /**
124
+ * Current-month sales projection for the histogram's last bucket: the average sales
125
+ * per business day over the last 5 business days, extended over the business days
126
+ * left in the month. Business days are UTC weekdays (Mon–Fri) — no holiday calendar.
127
+ * Today is excluded on both sides: it is still filling up (its sales land in the
128
+ * month's actual count as they happen).
129
+ */
130
+ export type SalesReportProjection = {
131
+ /** The projected month, `YYYY-MM` — always the histogram's last bucket. */
132
+ month: string;
133
+ /** Average sales per business day over the last 5 business days. */
134
+ salesPerBusinessDay: number;
135
+ /** Business days (Mon–Fri, UTC) left in the month after today. */
136
+ businessDaysLeft: number;
137
+ /** Expected further sales this month: `salesPerBusinessDay × businessDaysLeft` (unrounded). */
138
+ projectedRemaining: number;
139
+ };
140
+
123
141
  /**
124
142
  * Age-of-stock bands, in days of capital tied up. Cut points at 30 / 90 / 180 days,
125
143
  * upper bound inclusive; the last band is open-ended, so `180+` means "181 and over".
@@ -129,15 +147,22 @@ export const STOCK_AGE_BANDS = ['0-30', '31-90', '91-180', '180+'] as const;
129
147
  export type StockAgeBand = (typeof STOCK_AGE_BANDS)[number];
130
148
 
131
149
  /**
132
- * One day on the stock-age chart, measured by capital tied up in inventory. A vehicle
133
- * counts on `date` when the supplier was fully paid on or before that day and it had not
134
- * been sold yet; its age is `date − supplierFullyPaidAt` in days. Used vehicles only.
150
+ * One monthly snapshot on the stock-age charts, measured by capital tied up in
151
+ * inventory. A vehicle counts on `date` when the supplier was fully paid on or before
152
+ * that day and it had not been sold yet; its age is `date − supplierFullyPaidAt` in
153
+ * days. Used vehicles only.
135
154
  */
136
155
  export type StockAgePoint = {
137
- /** Snapshot day, `YYYY-MM-DD` (UTC). */
156
+ /** Snapshot day — the 1st of a month, `YYYY-MM-DD` (UTC). */
138
157
  date: string;
139
158
  /** In-stock vehicle count per age band on that day. */
140
159
  counts: Record<StockAgeBand, number>;
160
+ /**
161
+ * Sum of those vehicles' purchase costs per age band on that day (`deal.purchase`,
162
+ * excl VAT, tenant currency). A vehicle without a recorded purchase cost still counts
163
+ * in `counts` but contributes 0 here.
164
+ */
165
+ purchaseCosts: Record<StockAgeBand, number>;
141
166
  };
142
167
 
143
168
  export type SalesReportResponse = {
@@ -178,10 +203,12 @@ export type SalesReportResponse = {
178
203
  conglomerate: SalesReportConglomerate;
179
204
  /** Fixed last-18-calendar-months histogram of opps into Preparation (period-independent). */
180
205
  histogram: SalesReportHistogramBucket[];
206
+ /** Current-month projection, stacked on the histogram's last bucket by the client. */
207
+ projection: SalesReportProjection;
181
208
  /**
182
- * Stock-age evolution measured as capital tied up in inventory: one daily snapshot of
183
- * vehicles by days from supplier-fully-paid to sold (used vehicles). Fixed to the last
184
- * 6 months, period-independent.
209
+ * Stock-age evolution measured as capital tied up in inventory: one snapshot per
210
+ * month-1st of vehicles by days from supplier-fully-paid to sold (used vehicles).
211
+ * Fixed to the last 24 months, period-independent.
185
212
  */
186
213
  stockAge: StockAgePoint[];
187
214
  /**
@@ -142,6 +142,18 @@ export type Branch = {
142
142
  location: LocationValue;
143
143
 
144
144
  storecoveExternalId?: number;
145
+ // true if the branch is for a company where VAT is due when the invoice
146
+ // is issued not when the payment is collected (e.g. France, Italy, Spain)
147
+ vatOnDebits?: boolean;
148
+ /**
149
+ * The French issuing duties — e-invoicing, e-reporting and the Encaissée status — are switched
150
+ * on for this branch. Receiving is unaffected and always active.
151
+ *
152
+ * Kept separate from `storecoveExternalId` on purpose: registering a Storecove legal entity only
153
+ * makes a branch reachable, it does not mean the French duties have started. As a PME those
154
+ * duties begin 2027-09-01, so this stays off until then or until a deliberate earlier adoption.
155
+ */
156
+ frIssuingEnabled?: boolean;
145
157
  externalQuote?: boolean;
146
158
  hyperdmsId?: string;
147
159
  internalDealsEnabled?: boolean;
@@ -22,7 +22,6 @@ export type MetricConfig = {
22
22
  commissionType: CommissionType;
23
23
  personal: boolean; // if true, this metric is personal to the user
24
24
  format?: Intl.NumberFormatOptions;
25
- listVehicles?: boolean; // should this metric be allowed to list vehicles?
26
25
  defaultTarget?: number; // default target for the metric, useful for showing metrics to users w/o a commission plan
27
26
  autoHide?: boolean; // hide in UI when annual value is 0
28
27
  manualEntry?: boolean; // if true, data comes from manually added entries instead of vehicle_business_overviews
@@ -0,0 +1,49 @@
1
+ import {
2
+ WhatsappActivityTemplateName,
3
+ WhatsappTemplateTranslation,
4
+ } from '@bisondesk/commons-sdk/notifications-whatsapp';
5
+ import { BusinessEntityIds } from '../constants.js';
6
+ import { Activity } from './activities.js';
7
+ import { DataRecord } from './utils.js';
8
+
9
+ export type { WhatsappActivityTemplateName };
10
+
11
+ export type WhatsappTemplateLanguage = {
12
+ language: string;
13
+ status: string;
14
+ };
15
+
16
+ export type WhatsappTemplateSummary = {
17
+ name: WhatsappActivityTemplateName;
18
+ languages: WhatsappTemplateLanguage[];
19
+ };
20
+
21
+ export type WhatsappActivityTemplateTranslation =
22
+ WhatsappTemplateTranslation<WhatsappActivityTemplateName>;
23
+
24
+ export type WhatsappTemplatePreview = {
25
+ sent: WhatsappActivityTemplateTranslation;
26
+ canonical?: WhatsappActivityTemplateTranslation;
27
+ };
28
+
29
+ export type WhatsappRecipient = {
30
+ contactId?: string;
31
+ organizationId?: string;
32
+ phone: string;
33
+ countryLanguage?: string;
34
+ };
35
+
36
+ export type WhatsappActivityContext = {
37
+ businessEntityId: BusinessEntityIds;
38
+ recordId: string;
39
+ organizationId?: string;
40
+ };
41
+
42
+ export type SendWhatsappActivityTemplateRequest = {
43
+ templateName: WhatsappActivityTemplateName;
44
+ language: string;
45
+ recipient: Pick<WhatsappRecipient, 'contactId' | 'phone'>;
46
+ context: WhatsappActivityContext;
47
+ };
48
+
49
+ export type SendWhatsappActivityTemplateResponse = DataRecord<Activity>;