@bergetai/odoo-cli 0.5.1 → 0.5.3

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/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import { leadsCreateCommand, leadsDeleteCommand, leadsListCommand, leadsShowComm
5
5
  import { teamsCreateCommand, teamsDeleteCommand, teamsListCommand, teamsShowCommand, teamsUpdateCommand, crmTeams, } from "./commands/teams.js";
6
6
  import { ticketsCreateCommand, ticketsDeleteCommand, ticketsListCommand, ticketsShowCommand, ticketsUpdateCommand, helpdeskTickets, } from "./commands/helpdesk.js";
7
7
  import { addNoteCommand, listMessagesCommand, } from "./commands/notes.js";
8
- import { activitiesListCommand, activityDoneCommand, scheduleCommand, } from "./commands/activities.js";
8
+ import { activitiesListCommand, activityDoneCommand, activityUpdateCommand, scheduleCommand, } from "./commands/activities.js";
9
9
  import { createTaskCommand, projectListCommand, projectShowCommand, tasksListCommand, tasksShowCommand, } from "./commands/project.js";
10
10
  import { documentsDocuments, documentsListCommand, foldersListCommand, documentsShowCommand, documentsCreateCommand, documentsUpdateCommand, documentsDeleteCommand, treeCommand, uploadCommand, } from "./commands/documents.js";
11
11
  import { versionCommand } from "./commands/version.js";
@@ -227,6 +227,30 @@ Examples:
227
227
  .action(async (ids) => {
228
228
  await run((g) => activityDoneCommand(ids, g), program);
229
229
  });
230
+ leads
231
+ .command("activity-update")
232
+ .description("update activities — deadline, summary, note, type, assignee (preview with --dry-run)")
233
+ .argument("<id...>", "activity ids")
234
+ .option("--deadline <yyyy-mm-dd>", "new deadline")
235
+ .option("--summary <text>", "new summary")
236
+ .option("--note <text>", "new note")
237
+ .option("--type <name|id>", "new activity type (e.g. To-Do, Call, Meeting)")
238
+ .option("--assignee <name|id>", "new assignee (login, email, or name)")
239
+ .addHelpText("after", `
240
+ Updates mail.activity records directly via write. At least one field is required.
241
+
242
+ Examples:
243
+ # Push an activity deadline to tomorrow
244
+ $ odoo crm records activity-update 736 --deadline 2026-08-28
245
+
246
+ # Update summary + deadline for two activities
247
+ $ odoo crm records activity-update 736 731 --deadline 2026-08-28 --summary "Follow-up"
248
+
249
+ # Dry run
250
+ $ odoo crm records activity-update 736 --deadline 2026-08-28 --dry-run`)
251
+ .action(async (ids, opts) => {
252
+ await run((g) => activityUpdateCommand(ids, opts, g), program);
253
+ });
230
254
  const teams = crm.command("teams").description("sales teams (crm.team)");
231
255
  teams
232
256
  .command("list")
@@ -180,6 +180,101 @@ export async function activityDoneCommand(activityIds, globals) {
180
180
  console.log(`✓ Marked ${ids.length} activity(ies) as done: ${ids.join(", ")}`);
181
181
  }
182
182
  }
183
+ /**
184
+ * Update one or more activities (mail.activity) — deadline, summary, note,
185
+ * type, or assignee. Uses `write` directly on mail.activity.
186
+ */
187
+ export async function activityUpdateCommand(activityIds, opts, globals) {
188
+ const ids = activityIds.map((raw) => {
189
+ const n = Number.parseInt(raw, 10);
190
+ if (Number.isNaN(n) || n <= 0) {
191
+ throw usageError(`invalid activity id: ${raw}`, "provide a positive integer");
192
+ }
193
+ return n;
194
+ });
195
+ if (!opts.deadline && !opts.summary && opts.note === undefined && !opts.type && !opts.assignee) {
196
+ throw usageError("no fields to update", "provide at least one of --deadline, --summary, --note, --type, --assignee");
197
+ }
198
+ const client = await buildClient(globals);
199
+ // Verify the activities exist
200
+ const rows = (await client.executeKw("mail.activity", "search_read", [[["id", "in", ids]]], {
201
+ fields: ["id", "summary", "date_deadline", "state", "activity_type_id", "user_id"],
202
+ limit: ids.length,
203
+ }));
204
+ const byId = new Map(rows.map((r) => [r.id, r]));
205
+ const missing = ids.filter((id) => !byId.has(id));
206
+ if (missing.length > 0) {
207
+ throw notFoundError("record_not_found", `no mail.activity record(s) with id(s): ${missing.join(", ")}`, "no activities were modified — aborts the whole batch when any id is missing");
208
+ }
209
+ const values = {};
210
+ if (opts.deadline) {
211
+ values.date_deadline = parseDate(opts.deadline, "--deadline");
212
+ }
213
+ if (opts.summary) {
214
+ values.summary = opts.summary;
215
+ }
216
+ if (opts.note !== undefined) {
217
+ values.note = opts.note;
218
+ }
219
+ if (opts.type) {
220
+ const activityType = await resolveReference(client, "mail.activity.type", opts.type, {
221
+ label: "activity type",
222
+ });
223
+ values.activity_type_id = activityType.id;
224
+ }
225
+ if (opts.assignee) {
226
+ const user = await resolveReference(client, "res.users", opts.assignee, {
227
+ label: "user",
228
+ searchFields: ["login", "email", "name"],
229
+ });
230
+ values.user_id = user.id;
231
+ }
232
+ if (globals.verbose) {
233
+ logVerbose(`Updating ${ids.length} activity(ies): ${JSON.stringify(values)}`, globals.verbose);
234
+ }
235
+ if (globals.dryRun) {
236
+ if (globals.json) {
237
+ printJson({
238
+ model: "mail.activity",
239
+ action: "update",
240
+ dry_run: true,
241
+ ids,
242
+ values,
243
+ activities: rows.map((r) => ({
244
+ id: r.id,
245
+ summary: r.summary,
246
+ date_deadline: r.date_deadline,
247
+ state: r.state,
248
+ })),
249
+ });
250
+ }
251
+ else {
252
+ console.log(`[DRY RUN] Would update ${ids.length} activity(ies):`);
253
+ for (const r of rows) {
254
+ console.log(` #${r.id} — ${r.summary} (deadline: ${r.date_deadline ?? "none"}, state: ${r.state})`);
255
+ }
256
+ console.log(` New values: ${JSON.stringify(values, null, 2)}`);
257
+ }
258
+ return;
259
+ }
260
+ await client.executeKw("mail.activity", "write", [ids, values]);
261
+ if (globals.json) {
262
+ printJson({
263
+ model: "mail.activity",
264
+ action: "update",
265
+ dry_run: false,
266
+ updated: ids,
267
+ values,
268
+ });
269
+ }
270
+ else {
271
+ console.log(`✓ Updated ${ids.length} activity(ies): ${ids.join(", ")}`);
272
+ if (opts.deadline)
273
+ console.log(` New deadline: ${values.date_deadline}`);
274
+ if (opts.summary)
275
+ console.log(` New summary: ${values.summary}`);
276
+ }
277
+ }
183
278
  /**
184
279
  * List activities for a crm.lead record.
185
280
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bergetai/odoo-cli",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Agent-first CLI for the Odoo External API",
5
5
  "publishConfig": {
6
6
  "access": "public"