Corin1998 commited on
Commit
98e795b
·
verified ·
1 Parent(s): 0c586ff

Upload main.py

Browse files
Files changed (1) hide show
  1. main.py +87 -0
main.py CHANGED
@@ -447,3 +447,90 @@ def root_redirect():
447
  from openai_integration import router as ai_router
448
  app.include_router(ai_router, prefix="/ai", tags=["ai"])
449
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  from openai_integration import router as ai_router
448
  app.include_router(ai_router, prefix="/ai", tags=["ai"])
449
 
450
+ # ===== ここから追記(main.py の import 群より下ならどこでもOK) =====
451
+ from pydantic import Field
452
+
453
+ class WizardItemIn(BaseModel):
454
+ description: str
455
+ quantity: float = Field(gt=0, default=1)
456
+ unit_price: float = Field(ge=0)
457
+ tax_rate: float = Field(ge=0, default=0.0)
458
+
459
+ class WizardCustomerIn(BaseModel):
460
+ # 既存顧客を使うなら id を、無ければ name 等で新規作成
461
+ id: int | None = None
462
+ name: str | None = None
463
+ email: str | None = None
464
+ phone: str | None = None
465
+ address: str | None = None
466
+ city: str | None = None
467
+ country: str | None = None
468
+
469
+ class WizardInvoiceIn(BaseModel):
470
+ customer: WizardCustomerIn
471
+ due_date: date | None = None
472
+ notes: str | None = None
473
+ items: list[WizardItemIn]
474
+
475
+ class WizardInvoiceOut(BaseModel):
476
+ customer_id: int
477
+ invoice_id: int
478
+ totals: MoneyBreakdown
479
+
480
+ @app.post("/wizard/invoice", dependencies=[Depends(require_api_key)], response_model=WizardInvoiceOut)
481
+ def wizard_create_invoice(payload: WizardInvoiceIn, session: Session = Depends(get_session)):
482
+ """
483
+ 顧客IDがあればそれを使用。無ければ name などから顧客を新規作成。
484
+ その後、請求書を作成し、明細を一括登録して totals を返す。
485
+ """
486
+ # 1) 顧客を決定
487
+ cust_id: int | None = payload.customer.id
488
+ if cust_id:
489
+ cust = session.get(Customer, cust_id)
490
+ if not cust:
491
+ raise HTTPException(404, "Customer id not found")
492
+ else:
493
+ if not payload.customer.name:
494
+ raise HTTPException(422, "Either customer.id or customer.name is required")
495
+ # 既存に同名があればそれを使い、無ければ作成(簡易重複回避)
496
+ existing = session.exec(
497
+ select(Customer).where(Customer.name == payload.customer.name)
498
+ ).first()
499
+ if existing:
500
+ cust = existing
501
+ else:
502
+ cust = Customer(
503
+ name=payload.customer.name.strip(),
504
+ email=(payload.customer.email or None),
505
+ phone=(payload.customer.phone or None),
506
+ address=(payload.customer.address or None),
507
+ city=(payload.customer.city or None),
508
+ country=(payload.customer.country or None),
509
+ )
510
+ session.add(cust)
511
+ session.commit()
512
+ session.refresh(cust)
513
+ cust_id = cust.id
514
+
515
+ # 2) 請求書を作成
516
+ inv = Invoice(customer_id=cust_id, due_date=payload.due_date, notes=payload.notes)
517
+ session.add(inv)
518
+ session.commit()
519
+ session.refresh(inv)
520
+
521
+ # 3) 明細を一括追加
522
+ for it in payload.items:
523
+ session.add(InvoiceItem(
524
+ invoice_id=inv.id,
525
+ description=it.description,
526
+ quantity=it.quantity,
527
+ unit_price=it.unit_price,
528
+ tax_rate=it.tax_rate,
529
+ ))
530
+ session.commit()
531
+
532
+ items = session.exec(select(InvoiceItem).where(InvoiceItem.invoice_id == inv.id)).all()
533
+ totals = compute_totals(items)
534
+
535
+ return WizardInvoiceOut(customer_id=cust_id, invoice_id=inv.id, totals=totals)
536
+ # ===== 追記ここまで =====