Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 68 additions & 19 deletions billing/v1/billing.proto
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,9 @@ service Billing {
};
}

// Validates or imports monthly FreeFormItems from CSV through invoice settings.
// Validates or imports monthly FreeFormItems from CSV through invoice settings. The CSV
// supplies each row's own billing month, billing group, and vendor; there is no
// request-level billing_month or vendor to scope the call.
rpc BulkImportMonthlyMiscFees(BulkImportMonthlyMiscFeesRequest) returns (MonthlyMiscFeeImportResult) {
option (google.api.http) = {
post: "/v1/monthly-misc-fees:bulkImport"
Expand Down Expand Up @@ -2888,28 +2890,45 @@ message GetMonthlyMiscFeeImportTemplateRequest {
message MonthlyMiscFeeImportTemplate {
string format = 1;
string format_version = 2;

// CSV header columns in required order. Has no "enabled" column: every item the
// workflow imports is saved as enabled.
repeated string headers = 3;

repeated string sample_row = 4;

// Supported values for BulkImportMonthlyMiscFeesRequest.mode: "merge" and "replace".
// Preview vs. apply is controlled separately by BulkImportMonthlyMiscFeesRequest.dry_run,
// not by this field.
repeated string allowed_modes = 5;

int64 max_file_size_bytes = 6;
int32 max_rows = 7;
}

// No billing_month or vendor field: each CSV row supplies its own, so one upload can span
// any combination of billing groups, vendors, and invoice months.
message BulkImportMonthlyMiscFeesRequest {
// Required. Selected billing cycle in YYYY-MM form; YYYYMM is normalized.
string billing_month = 1 [(google.api.field_behavior) = REQUIRED];

// Required. Uploaded CSV content as normalized UTF-8 text.
string csv_content = 2 [(google.api.field_behavior) = REQUIRED];
string csv_content = 1 [(google.api.field_behavior) = REQUIRED];

// Required. Original upload file name for audit and result display.
string file_name = 3 [(google.api.field_behavior) = REQUIRED];
string file_name = 2 [(google.api.field_behavior) = REQUIRED];

// Required. "merge" upserts each row's item by label, leaving every other existing item for
// that billing group and vendor untouched. "replace" sets the complete additional-item list
// for each (billing_month, billing_group_id, vendor) combination the CSV names to exactly
// that combination's CSV rows, removing any existing item the CSV omits for it; a
// "replace" CSV must contain rows for exactly one billing_month, and the request is
// rejected before saving anything if it spans more than one.
string mode = 3 [(google.api.field_behavior) = REQUIRED];

// Required. "dry-run" validates only; "merge" upserts FreeFormItems by label.
string mode = 4 [(google.api.field_behavior) = REQUIRED];
string format = 4 [(google.api.field_behavior) = REQUIRED];
string format_version = 5 [(google.api.field_behavior) = REQUIRED];

string format = 5 [(google.api.field_behavior) = REQUIRED];
string format_version = 6 [(google.api.field_behavior) = REQUIRED];
// Optional. When true, validates and returns the planned result for either mode without
// saving anything.
bool dry_run = 6;
}

message ListMonthlyMiscFeesRequest {
Expand Down Expand Up @@ -2948,22 +2967,48 @@ message MonthlyMiscFee {
string source = 11;
}

// No singular billing_month field: a result can now span multiple billing months. See
// billing_months below.
message MonthlyMiscFeeImportResult {
string status = 1;
string billing_month = 2;
string file_name = 3;
int32 total_rows = 4;
int32 valid_rows = 5;
int32 inserted_rows = 6;
int32 updated_rows = 7;
int32 unchanged_rows = 8;
int32 failed_rows = 9;
repeated MonthlyMiscFeeImportRowResult row_results = 10;
string file_name = 2;
int32 total_rows = 3;
int32 valid_rows = 4;
int32 inserted_rows = 5;
int32 updated_rows = 6;
int32 unchanged_rows = 7;
int32 failed_rows = 8;
repeated MonthlyMiscFeeImportRowResult row_results = 9;

// Existing items removed because a "replace"-mode CSV omitted them from a combination it
// touched. Always 0 in "merge" mode.
int32 removed_rows = 10;

// Every distinct billing month, in "YYYY-MM" form, a valid row in this file touches.
repeated string billing_months = 11;

// Every distinct vendor a valid row in this file touches.
repeated string vendors = 12;

// Every distinct billing group a valid row in this file touches.
repeated MonthlyMiscFeeImportGroupSummary billing_groups = 13;
}

message MonthlyMiscFeeImportGroupSummary {
string billing_group_id = 1;
string billing_group_name = 2;
}

message MonthlyMiscFeeImportRowResult {
// The 1-based CSV row this result corresponds to. 0 when action is "remove", since a
// removal has no corresponding CSV row.
int32 csv_row_number = 1;

// One of "insert", "update", "unchanged", "invalid", or "remove". "remove" only appears in
// "replace" mode, for an existing item the CSV silently drops from a combination it
// otherwise touches.
string action = 2;

string billing_group_id = 3;
string billing_group_name = 4;
string vendor = 5;
Expand All @@ -2973,6 +3018,10 @@ message MonthlyMiscFeeImportRowResult {
int64 amount = 9;
bool enabled = 10;
repeated MonthlyMiscFeeValidationError validation_errors = 11;

// The row's own billing month in "YYYY-MM" form. Always populated, including for "remove"
// results, since a request can span multiple months.
string billing_month = 12;
}

message MonthlyMiscFeeValidationError {
Expand Down
77 changes: 58 additions & 19 deletions openapiv2/apidocs.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -12471,7 +12471,8 @@
},
"/v1/monthly-misc-fees:bulkImport": {
"post": {
"summary": "Validates or imports monthly miscellaneous fees from CSV.",
"summary": "Validates or imports monthly FreeFormItems from CSV through invoice settings.",
"description": "The CSV supplies each row's own billing month, billing group, and vendor; there is no\nrequest-level billing_month or vendor to scope the call.",
"operationId": "Billing_BulkImportMonthlyMiscFees",
"responses": {
"200": {
Expand Down Expand Up @@ -36446,21 +36447,17 @@
"v1BulkImportMonthlyMiscFeesRequest": {
"type": "object",
"properties": {
"billingMonth": {
"type": "string",
"description": "Required. Selected billing cycle in YYYY-MM form; YYYYMM is accepted and normalized by the server."
},
"csvContent": {
"type": "string",
"description": "Required. Uploaded CSV content as normalized UTF-8 text."
},
"fileName": {
"type": "string",
"description": "Required. Original upload file name for audit metadata."
"description": "Required. Original upload file name for audit and result display."
},
"mode": {
"type": "string",
"description": "Required. One of \"dry-run\", \"replace-month\", or \"merge\". Empty defaults to \"dry-run\"."
"description": "Required. \"merge\" upserts each row's item by label, leaving every other existing item for\nthat billing group and vendor untouched. \"replace\" sets the complete additional-item list\nfor each (billing_month, billing_group_id, vendor) combination the CSV names to exactly\nthat combination's CSV rows, removing any existing item the CSV omits for it; a\n\"replace\" CSV must contain rows for exactly one billing_month, and the request is\nrejected before saving anything if it spans more than one."
},
"format": {
"type": "string",
Expand All @@ -36470,13 +36467,13 @@
"type": "string",
"description": "Required. Import format version. Currently \"misc_fee_import_v1\"."
},
"idempotencyKey": {
"type": "string",
"description": "Optional. Idempotency key for write-mode imports."
"dryRun": {
"type": "boolean",
"description": "Optional. When true, validates and returns the planned result for either mode without\nsaving anything."
}
},
"description": "No billing_month or vendor field: each CSV row supplies its own, so one upload can span\nany combination of billing groups, vendors, and invoice months.",
"required": [
"billingMonth",
"csvContent",
"fileName",
"mode",
Expand Down Expand Up @@ -44670,13 +44667,21 @@
}
}
},
"v1MonthlyMiscFeeImportResult": {
"v1MonthlyMiscFeeImportGroupSummary": {
"type": "object",
"properties": {
"status": {
"billingGroupId": {
"type": "string"
},
"billingMonth": {
"billingGroupName": {
"type": "string"
}
}
},
"v1MonthlyMiscFeeImportResult": {
"type": "object",
"properties": {
"status": {
"type": "string"
},
"fileName": {
Expand Down Expand Up @@ -44712,18 +44717,48 @@
"type": "object",
"$ref": "#/definitions/v1MonthlyMiscFeeImportRowResult"
}
},
"removedRows": {
"type": "integer",
"format": "int32",
"description": "Existing items removed because a \"replace\"-mode CSV omitted them from a combination it\ntouched. Always 0 in \"merge\" mode."
},
"billingMonths": {
"type": "array",
"items": {
"type": "string"
},
"description": "Every distinct billing month, in \"YYYY-MM\" form, a valid row in this file touches."
},
"vendors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Every distinct vendor a valid row in this file touches."
},
"billingGroups": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/v1MonthlyMiscFeeImportGroupSummary"
},
"description": "Every distinct billing group a valid row in this file touches."
}
}
},
"description": "No singular billing_month field: a result can now span multiple billing months. See\nbilling_months below."
},
"v1MonthlyMiscFeeImportRowResult": {
"type": "object",
"properties": {
"csvRowNumber": {
"type": "integer",
"format": "int32"
"format": "int32",
"description": "The 1-based CSV row this result corresponds to. 0 when action is \"remove\", since a\nremoval has no corresponding CSV row."
},
"action": {
"type": "string"
"type": "string",
"description": "One of \"insert\", \"update\", \"unchanged\", \"invalid\", or \"remove\". \"remove\" only appears in\n\"replace\" mode, for an existing item the CSV silently drops from a combination it\notherwise touches."
},
"billingGroupId": {
"type": "string"
Expand Down Expand Up @@ -44758,6 +44793,10 @@
"type": "object",
"$ref": "#/definitions/v1MonthlyMiscFeeValidationError"
}
},
"billingMonth": {
"type": "string",
"description": "The row's own billing month in \"YYYY-MM\" form. Always populated, including for \"remove\"\nresults, since a request can span multiple months."
}
}
},
Expand All @@ -44777,7 +44816,7 @@
"items": {
"type": "string"
},
"description": "CSV header columns in required order."
"description": "CSV header columns in required order. Has no \"enabled\" column: every item the\nworkflow imports is saved as enabled."
},
"sampleRow": {
"type": "array",
Expand All @@ -44791,7 +44830,7 @@
"items": {
"type": "string"
},
"description": "Supported modes: \"dry-run\", \"replace-month\", and \"merge\"."
"description": "Supported values for BulkImportMonthlyMiscFeesRequest.mode: \"merge\" and \"replace\".\nPreview vs. apply is controlled separately by BulkImportMonthlyMiscFeesRequest.dry_run,\nnot by this field."
},
"maxFileSizeBytes": {
"type": "string",
Expand Down
Loading