feat(crm): invoice update notes and PO fields

Allow oo invoices update --description/--po so Notizen can be
multiline refs without portal URLs; keep opportunity link support.
This commit is contained in:
2026-08-06 12:47:06 +01:00
parent 3201a58df7
commit d81e7de911
2 changed files with 26 additions and 9 deletions
+12 -5
View File
@@ -160,21 +160,26 @@ Example:
func invoiceUpdateCmd() *cobra.Command { func invoiceUpdateCmd() *cobra.Command {
var opportunityID int64 var opportunityID int64
var description, po string
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "update INVOICE_ID", Use: "update INVOICE_ID",
Short: "Update invoice (link to opportunity)", Short: "Update invoice (opportunity link, notes, PO)",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if opportunityID == 0 { if opportunityID == 0 && !cmd.Flags().Changed("description") && !cmd.Flags().Changed("po") {
return fmt.Errorf("--opportunity is required") return fmt.Errorf("set --opportunity and/or --description and/or --po")
} }
c, err := newOO(cmd) c, err := newOO(cmd)
if err != nil { if err != nil {
return err return err
} }
out, err := c.UpdateInvoice(cmd.Context(), args[0], onlyoffice.UpdateInvoiceParams{ out, err := c.UpdateInvoice(cmd.Context(), args[0], onlyoffice.UpdateInvoiceParams{
EntityID: opportunityID, EntityID: opportunityID,
EntityType: 0, EntityType: 0,
Description: description,
DescriptionSet: cmd.Flags().Changed("description"),
PurchaseOrder: po,
PurchaseOrderSet: cmd.Flags().Changed("po"),
}) })
if err != nil { if err != nil {
return err return err
@@ -184,6 +189,8 @@ func invoiceUpdateCmd() *cobra.Command {
}, },
} }
cmd.Flags().Int64Var(&opportunityID, "opportunity", 0, "CRM opportunity/deal id to link") cmd.Flags().Int64Var(&opportunityID, "opportunity", 0, "CRM opportunity/deal id to link")
cmd.Flags().StringVar(&description, "description", "", "invoice notes (Notizen); use \\n for line breaks")
cmd.Flags().StringVar(&po, "po", "", "purchase order number")
return cmd return cmd
} }
+14 -4
View File
@@ -115,11 +115,15 @@ func (c *Client) CreateInvoice(ctx context.Context, p CreateInvoiceParams) (map[
} }
// UpdateInvoiceParams are fields for PUT /api/2.0/crm/invoice/{id}. // UpdateInvoiceParams are fields for PUT /api/2.0/crm/invoice/{id}.
// Loads the current invoice and merges non-zero entity / contact updates. // Loads the current invoice and merges non-zero / set fields.
type UpdateInvoiceParams struct { type UpdateInvoiceParams struct {
EntityID int64 // link to opportunity; 0 = leave unchanged EntityID int64 // link to opportunity; 0 = leave unchanged
EntityType int EntityType int
ContactID int64 // 0 = leave unchanged ContactID int64 // 0 = leave unchanged
Description string // invoice notes; empty + DescriptionSet=false keeps existing
DescriptionSet bool
PurchaseOrder string
PurchaseOrderSet bool
} }
// UpdateInvoice PUTs a full invoice body (OnlyOffice requires complete payload). // UpdateInvoice PUTs a full invoice body (OnlyOffice requires complete payload).
@@ -196,6 +200,12 @@ func (c *Client) UpdateInvoice(ctx context.Context, id string, p UpdateInvoicePa
"status": statusID, "status": statusID,
"invoiceLines": lines, "invoiceLines": lines,
} }
if p.DescriptionSet {
body["description"] = p.Description
}
if p.PurchaseOrderSet {
body["purchaseOrderNumber"] = p.PurchaseOrder
}
if p.EntityID != 0 { if p.EntityID != 0 {
body["entityId"] = p.EntityID body["entityId"] = p.EntityID
body["entityType"] = p.EntityType body["entityType"] = p.EntityType