makea-cli 0.2.9__py3-none-any.whl → 0.2.11__py3-none-any.whl

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.
makea_cli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.2.9"
1
+ __version__ = "0.2.11"
makea_cli/api_client.py CHANGED
@@ -1062,6 +1062,43 @@ def supplier_list_production_orders(*, quote_request_id: str | None = None) -> A
1062
1062
  return get_json("/supplier/production_orders", params=params)
1063
1063
 
1064
1064
 
1065
+ def supplier_get_orders(quote_request_id: str, *, readable: bool = False) -> Any:
1066
+ """GET /supplier/quote_requests/{id}/orders_view — the sample and bulk orders
1067
+ on one RFQ. ``readable``: each order's state, dates and what was paid, with
1068
+ no ids or product payload (the full view runs past 100KB)."""
1069
+ params = {"view": "readable"} if readable else None
1070
+ return get_json(f"/supplier/quote_requests/{quote_request_id}/orders_view", params=params)
1071
+
1072
+
1073
+ def supplier_list_milestones(production_order_id: str) -> Any:
1074
+ """GET /supplier/production_orders/{id}/progress?view=readable — each step's
1075
+ milestones, which one came back and why, and the proof review's view."""
1076
+ return get_json(
1077
+ f"/supplier/production_orders/{production_order_id}/progress",
1078
+ params={"view": "readable"},
1079
+ )
1080
+
1081
+
1082
+ def supplier_get_payment_summary(quote_request_id: str) -> Any:
1083
+ """GET /supplier/quote_requests/{id}/payment_summary — whether the buyer has
1084
+ paid each stage, and the factory's own price on its purchase orders."""
1085
+ return get_json(f"/supplier/quote_requests/{quote_request_id}/payment_summary")
1086
+
1087
+
1088
+ def supplier_list_purchase_orders() -> Any:
1089
+ """GET /supplier/purchase-orders — purchase orders raised to this factory."""
1090
+ return get_json("/supplier/purchase-orders")
1091
+
1092
+
1093
+ def supplier_list_order_notes(
1094
+ *, production_order_id: str | None = None, sampling_order_id: str | None = None
1095
+ ) -> Any:
1096
+ """GET /supplier/{production|sampling}_orders/{id}/notes — an order's notes."""
1097
+ if production_order_id:
1098
+ return get_json(f"/supplier/production_orders/{production_order_id}/notes")
1099
+ return get_json(f"/supplier/sampling_orders/{sampling_order_id}/notes")
1100
+
1101
+
1065
1102
  def supplier_list_actions() -> Any:
1066
1103
  """GET /supplier/actions — what the platform is waiting on this factory for."""
1067
1104
  return get_json("/supplier/actions")
@@ -1359,6 +1396,99 @@ def supplier_list_quote_edit_requests(quote_request_id: str) -> Any:
1359
1396
  return get_json(f"/supplier/quote_requests/{quote_request_id}/quote_edit_requests")
1360
1397
 
1361
1398
 
1399
+ def designer_get_tna() -> Any:
1400
+ """GET /designer/tna_calendar — every pack's five steps and arrival, with
1401
+ the launch it is measured against when the arrival is confirmed."""
1402
+ return get_json("/designer/tna_calendar")
1403
+
1404
+
1405
+ def designer_list_milestones(product_id: str) -> Any:
1406
+ """Production milestones on a pack's bulk orders, compact: what is done,
1407
+ submitted or waiting, never a lateness the factory did not commit to."""
1408
+ raw = get_json(
1409
+ f"/designer/products/{product_id}/production_order_details",
1410
+ params={"type": "PRODUCTION"},
1411
+ )
1412
+ orders = (
1413
+ raw.get("production_orders_details") or raw.get("orders")
1414
+ if isinstance(raw, dict)
1415
+ else raw
1416
+ )
1417
+ out = []
1418
+ for order in orders or []:
1419
+ if not isinstance(order, dict):
1420
+ continue
1421
+ for step in order.get("production_progress") or []:
1422
+ meta = step.get("metadata") or {}
1423
+ for m in meta.get("milestones") or []:
1424
+ if not isinstance(m, dict):
1425
+ continue
1426
+ out.append(
1427
+ {
1428
+ "order_id": order.get("production_order_id"),
1429
+ "step": step.get("progress_type"),
1430
+ "milestone": m.get("title"),
1431
+ "status": m.get("status"),
1432
+ "days_from_payment": m.get("time_window"),
1433
+ "submitted_at": m.get("submitted_at"),
1434
+ "approval_result": m.get("approval_result"),
1435
+ "completed_at": m.get("completed_at"),
1436
+ }
1437
+ )
1438
+ return {"product_id": product_id, "milestones": out}
1439
+
1440
+
1441
+ def designer_list_notes(
1442
+ product_id: str, channel_key: str, *, since: str | None = None
1443
+ ) -> Any:
1444
+ """A channel's messages, oldest first, optionally only those after
1445
+ ``since`` (ISO date or datetime): what the factory said this week."""
1446
+ raw = get_json(f"/designer/products/{product_id}/channels/{channel_key}/notes")
1447
+ notes = raw.get("notes") if isinstance(raw, dict) else raw
1448
+ out = []
1449
+ for n in notes or []:
1450
+ if not isinstance(n, dict):
1451
+ continue
1452
+ if since and str(n.get("created_at") or "") < since:
1453
+ continue
1454
+ out.append(
1455
+ {
1456
+ "note_id": n.get("note_id"),
1457
+ "at": n.get("created_at"),
1458
+ "from": n.get("created_by_type"),
1459
+ "supplier": n.get("supplier_name"),
1460
+ "text": n.get("content"),
1461
+ "replies": len(n.get("replies") or []),
1462
+ }
1463
+ )
1464
+ return {"product_id": product_id, "channel": channel_key, "notes": out}
1465
+
1466
+
1467
+ def designer_list_fit_rounds(product_id: str) -> Any:
1468
+ """GET /designer/products/{id}/fit_rounds — every fit round on the pack and
1469
+ the corrections carried into bulk."""
1470
+ return get_json(f"/designer/products/{product_id}/fit_rounds")
1471
+
1472
+
1473
+ def designer_get_costing(style_id: str) -> Any:
1474
+ """One unit of each pack on a product card: factory price, fees, the
1475
+ brand's freight and duty estimates, target, RRP, margin."""
1476
+ raw = get_json(f"/designer/styles/{style_id}/overview")
1477
+ packs = raw.get("packs") if isinstance(raw, dict) else []
1478
+ return {
1479
+ "style_id": style_id,
1480
+ "packs": [
1481
+ {
1482
+ "product_id": p.get("product_id"),
1483
+ "pack": p.get("pack_label"),
1484
+ "costing": p.get("costing"),
1485
+ }
1486
+ for p in packs or []
1487
+ if isinstance(p, dict)
1488
+ ],
1489
+ }
1490
+
1491
+
1362
1492
  def designer_list_actions(*, product_id: str | None = None) -> Any:
1363
1493
  """GET /designer/actions — the brand's pending actions, optionally for one product."""
1364
1494
  params = {"product_id": product_id} if product_id else None
@@ -212,6 +212,95 @@ def register(app: typer.Typer) -> None:
212
212
  """List a product's channels."""
213
213
  print_json_or_exit(console, lambda: api_client.designer_list_channels(product))
214
214
 
215
+ @command(
216
+ app,
217
+ "designer",
218
+ "get",
219
+ "tna",
220
+ api="GET /designer/tna_calendar",
221
+ help=(
222
+ "GET /designer/tna_calendar — when each pack arrives and how sure that is "
223
+ "(done / confirmed / estimated), with its launch day."
224
+ ),
225
+ )
226
+ def get_tna() -> None:
227
+ """The Time & Action calendar."""
228
+ print_json_or_exit(console, lambda: api_client.designer_get_tna())
229
+
230
+ @command(
231
+ app,
232
+ "designer",
233
+ "list",
234
+ "milestone",
235
+ api="GET /designer/products/{product_id}/production_order_details",
236
+ help=(
237
+ "GET /designer/products/{id}/production_order_details — the bulk order's "
238
+ "production milestones: done, submitted, waiting."
239
+ ),
240
+ )
241
+ def list_milestones(
242
+ product: str = typer.Option(..., "--product", "-p", help="Product id."),
243
+ ) -> None:
244
+ """List a pack's production milestones."""
245
+ print_json_or_exit(console, lambda: api_client.designer_list_milestones(product))
246
+
247
+ @command(
248
+ app,
249
+ "designer",
250
+ "list",
251
+ "note",
252
+ api="GET /designer/products/{product_id}/channels/{channel_key}/notes",
253
+ help=(
254
+ "GET /designer/products/{id}/channels/{key}/notes — a channel's messages, "
255
+ "oldest first; --since keeps the recent ones (no keyword needed)."
256
+ ),
257
+ )
258
+ def list_notes(
259
+ product: str = typer.Option(..., "--product", "-p", help="Product id."),
260
+ channel: str = typer.Option(..., "--channel", "-c", help="Channel key."),
261
+ since: str | None = typer.Option(
262
+ None, "--since", help="ISO date or datetime, e.g. 2026-10-01."
263
+ ),
264
+ ) -> None:
265
+ """List a channel's messages."""
266
+ print_json_or_exit(
267
+ console, lambda: api_client.designer_list_notes(product, channel, since=since)
268
+ )
269
+
270
+ @command(
271
+ app,
272
+ "designer",
273
+ "list",
274
+ "fit-round",
275
+ api="GET /designer/products/{product_id}/fit_rounds",
276
+ help=(
277
+ "GET /designer/products/{id}/fit_rounds — the pack's fit rounds and the "
278
+ "corrections carried into bulk."
279
+ ),
280
+ )
281
+ def list_fit_rounds(
282
+ product: str = typer.Option(..., "--product", "-p", help="Product id."),
283
+ ) -> None:
284
+ """List a pack's fit rounds."""
285
+ print_json_or_exit(console, lambda: api_client.designer_list_fit_rounds(product))
286
+
287
+ @command(
288
+ app,
289
+ "designer",
290
+ "get",
291
+ "costing",
292
+ api="GET /designer/styles/{style_id}/overview",
293
+ help=(
294
+ "GET /designer/styles/{id}/overview — what one unit of each pack costs and "
295
+ "the margin at RRP (freight and duty are the brand's estimates)."
296
+ ),
297
+ )
298
+ def get_costing(
299
+ style: str = typer.Option(..., "--style", "-s", help="Product card (style) id."),
300
+ ) -> None:
301
+ """A product card's unit cost and margin."""
302
+ print_json_or_exit(console, lambda: api_client.designer_get_costing(style))
303
+
215
304
  @command(
216
305
  app,
217
306
  "designer",
@@ -96,11 +96,11 @@ def register(app: typer.Typer) -> None:
96
96
  "list",
97
97
  "production-order",
98
98
  api="GET /supplier/production_orders",
99
- help="GET /supplier/production_orders — your production orders, optionally for one RFQ.",
99
+ help="GET /supplier/production_orders?quote_request_id=… — the bulk orders on one RFQ.",
100
100
  )
101
101
  def list_production_orders(
102
- rfq: str | None = typer.Option(
103
- None, "--rfq", help="Only orders that grew out of this quote request."
102
+ rfq: str = typer.Option(
103
+ ..., "--rfq", help="The quote request whose orders to list (required)."
104
104
  ),
105
105
  ) -> None:
106
106
  """List the factory's production orders."""
@@ -108,6 +108,107 @@ def register(app: typer.Typer) -> None:
108
108
  console, lambda: api_client.supplier_list_production_orders(quote_request_id=rfq)
109
109
  )
110
110
 
111
+ @command(
112
+ app,
113
+ "supplier",
114
+ "get",
115
+ "order",
116
+ api="GET /supplier/quote_requests/{id}/orders_view",
117
+ help=(
118
+ "GET /supplier/quote_requests/{id}/orders_view — the sample and bulk orders on one RFQ."
119
+ ),
120
+ )
121
+ def get_order(
122
+ quote_request_id: str = typer.Argument(..., help="The quote request."),
123
+ readable: bool = typer.Option(
124
+ False,
125
+ "--readable",
126
+ help=(
127
+ "Each order's state, dates, quantity and what has been paid, with "
128
+ "no ids or product payload. The full view runs past 100KB."
129
+ ),
130
+ ),
131
+ ) -> None:
132
+ """Read the orders on one RFQ."""
133
+ print_json_or_exit(
134
+ console,
135
+ lambda: api_client.supplier_get_orders(quote_request_id, readable=readable),
136
+ )
137
+
138
+ @command(
139
+ app,
140
+ "supplier",
141
+ "list",
142
+ "milestone",
143
+ api="GET /supplier/production_orders/{id}/progress",
144
+ help=(
145
+ "GET /supplier/production_orders/{id}/progress?view=readable — each "
146
+ "step's milestones, which came back and why, and the proof review."
147
+ ),
148
+ )
149
+ def list_milestones(
150
+ production_order: str = typer.Option(
151
+ ..., "--production-order", help="The bulk order (from `get order`)."
152
+ ),
153
+ ) -> None:
154
+ """List a bulk order's production milestones."""
155
+ print_json_or_exit(console, lambda: api_client.supplier_list_milestones(production_order))
156
+
157
+ @command(
158
+ app,
159
+ "supplier",
160
+ "get",
161
+ "payment-summary",
162
+ api="GET /supplier/quote_requests/{id}/payment_summary",
163
+ help=(
164
+ "GET /supplier/quote_requests/{id}/payment_summary — whether the buyer "
165
+ "has paid the sample, deposit and balance, and your price on each PO."
166
+ ),
167
+ )
168
+ def get_payment_summary(
169
+ quote_request_id: str = typer.Argument(..., help="The quote request."),
170
+ ) -> None:
171
+ """Where the money for one RFQ stands, from the factory's side."""
172
+ print_json_or_exit(
173
+ console, lambda: api_client.supplier_get_payment_summary(quote_request_id)
174
+ )
175
+
176
+ @command(
177
+ app,
178
+ "supplier",
179
+ "list",
180
+ "purchase-order",
181
+ api="GET /supplier/purchase-orders",
182
+ help="GET /supplier/purchase-orders — the purchase orders raised to you.",
183
+ )
184
+ def list_purchase_orders() -> None:
185
+ """List the factory's purchase orders."""
186
+ print_json_or_exit(console, lambda: api_client.supplier_list_purchase_orders())
187
+
188
+ @command(
189
+ app,
190
+ "supplier",
191
+ "list",
192
+ "order-note",
193
+ api="GET /supplier/production_orders/{id}/notes",
194
+ help=("GET /supplier/{production|sampling}_orders/{id}/notes — the notes on one order."),
195
+ )
196
+ def list_order_notes(
197
+ production_order: str | None = typer.Option(
198
+ None, "--production-order", help="A bulk order."
199
+ ),
200
+ sampling_order: str | None = typer.Option(None, "--sampling-order", help="A sample order."),
201
+ ) -> None:
202
+ """List the notes on one order."""
203
+ if bool(production_order) == bool(sampling_order):
204
+ raise typer.BadParameter("Give exactly one of --production-order, --sampling-order")
205
+ print_json_or_exit(
206
+ console,
207
+ lambda: api_client.supplier_list_order_notes(
208
+ production_order_id=production_order, sampling_order_id=sampling_order
209
+ ),
210
+ )
211
+
111
212
  @command(
112
213
  app,
113
214
  "supplier",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: makea-cli
3
- Version: 0.2.9
3
+ Version: 0.2.11
4
4
  Summary: Makea admin CLI (browser login + Makea admin HTTP API)
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: click<9,>=8.1
@@ -1,6 +1,6 @@
1
- makea_cli/__init__.py,sha256=F8OVhAhMXSkvvXYgZtbPn2SG1AQC3joK4yu-FrHt81Y,22
1
+ makea_cli/__init__.py,sha256=_MLx4ac1juJPWEEiC9kMQISX3x3jFBr507jM2P_hxMg,23
2
2
  makea_cli/__main__.py,sha256=AkQjxWfKE3w9iD1d6I-2Zqvv2t9cct0oYyFF0UiA-Z0,144
3
- makea_cli/api_client.py,sha256=dzMCH9KzY7NJxoop-WVyqm_JQ3eU3hvFh_ic2Zk-evc,50763
3
+ makea_cli/api_client.py,sha256=3tQPSDMZTp67kiY_FZweO7gNFNapan-tq507GTvP5FE,56034
4
4
  makea_cli/auth_pkce.py,sha256=iXSyJ7DM3qVuj-3FwPiqM25CxXz9ebFs9FNthZdw3ws,7315
5
5
  makea_cli/broker.py,sha256=5O650nAdRuF-u9E1MuVM2jVv796iBdxJGIaJasxHij0,3019
6
6
  makea_cli/config.py,sha256=hz8MnJSkhxcIEZkcpHR005JrDceo1Xmi8qwIUq50cMU,3003
@@ -17,7 +17,7 @@ makea_cli/commands/analytics/cmd.py,sha256=KVLUtYSeyYZ8_09jIuIAmePjQqcpQS2mb5PBB
17
17
  makea_cli/commands/auth/__init__.py,sha256=NXoKGfkY2X_hb8GnAyzhoI_qDXfpwKZPqt4HnOrXW3Y,73
18
18
  makea_cli/commands/auth/cmd.py,sha256=G9ZeiaJwzUUTptIyynr0V-82wI7eV0qVX0pD6rdPSXg,1321
19
19
  makea_cli/commands/brand/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- makea_cli/commands/brand/cmd.py,sha256=khcU-vVYKh6fKs43bQTgGHdMCIYG5QP9lkgVnwsrAew,39177
20
+ makea_cli/commands/brand/cmd.py,sha256=lYT-9CRdOugVTGy2pJz9-RqdqWPIKIW10K8iSb0kQVE,42259
21
21
  makea_cli/commands/designer/__init__.py,sha256=Tc3Ju4-BKX2euBljhlrEd-Ksirk6JSPNixq4x0IbQYI,77
22
22
  makea_cli/commands/designer/cmd.py,sha256=4oOJ5tWYojUs8FBj3QRmgpwbicpsU1XqswoNlJpLLS8,23615
23
23
  makea_cli/commands/directory/__init__.py,sha256=rQHBc0JOFXynlzrBm_YfqoRuNsS-JOl-OOvPjgDbnIA,78
@@ -27,7 +27,7 @@ makea_cli/commands/document/cmd.py,sha256=IqjzGoTYXp1RbTIYY1MSEqX93btK4eESDTX40C
27
27
  makea_cli/commands/email/__init__.py,sha256=EWMqMTgZK1GQDW7-9RGVSGU-CvaHTARjXZL18Hdj80I,74
28
28
  makea_cli/commands/email/cmd.py,sha256=s22JQjJ7bPdpgBaL7Tmr8hx80ki_JN_iGQtUekXmmdo,4177
29
29
  makea_cli/commands/factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- makea_cli/commands/factory/cmd.py,sha256=ZMJ2UDSAI3vINvvltrH8VjSPWdsmUquVHQlANyb-G9Y,15131
30
+ makea_cli/commands/factory/cmd.py,sha256=k_UGkqpzxxZhN9WjKt1rb95KOTGHMpMJRpfNHTGZ_nA,18691
31
31
  makea_cli/commands/library/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  makea_cli/commands/library/cmd.py,sha256=eXZa6iLyPaoEWtRd-UmhRT6Ox-zlfs89gJqGn-IPuSU,11187
33
33
  makea_cli/commands/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -41,7 +41,7 @@ makea_cli/commands/production/cmd.py,sha256=s6fVAGzOvokF6Va5WKGEA2vw2x2hDQ3PrsF0
41
41
  makea_cli/commands/production/pricing_spec.py,sha256=xGbj7-ps3PcKuU6Oc59A70b62FjF6Awhr5IY3ymZveU,27174
42
42
  makea_cli/commands/supplier/__init__.py,sha256=qfQDeQdQ-B7I_uwFVfcp1vXFUTL4fAcNLu3ipsZ7dfs,77
43
43
  makea_cli/commands/supplier/cmd.py,sha256=crRCy9WfhkryHMIL3iufoiT90_SG3-mKChAtdhd06uc,58076
44
- makea_cli-0.2.9.dist-info/METADATA,sha256=Nnp67EfMAZJ0m9JEn9qhecii3iB4Xg0cEo1lUqVxn8I,31760
45
- makea_cli-0.2.9.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
46
- makea_cli-0.2.9.dist-info/entry_points.txt,sha256=4x-lbVa1jBbNlkNq7L-rYyfRh2spZmc3BLIzP-Dl-Qk,50
47
- makea_cli-0.2.9.dist-info/RECORD,,
44
+ makea_cli-0.2.11.dist-info/METADATA,sha256=Xee4upBM3q_z2hwAVk7OHlVufm1DHQF98gu5otOAHks,31761
45
+ makea_cli-0.2.11.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
46
+ makea_cli-0.2.11.dist-info/entry_points.txt,sha256=4x-lbVa1jBbNlkNq7L-rYyfRh2spZmc3BLIzP-Dl-Qk,50
47
+ makea_cli-0.2.11.dist-info/RECORD,,