顧客参照長押しで編集
This commit is contained in:
parent
ba04a77062
commit
50aa460064
2 changed files with 74 additions and 64 deletions
131
main.py
131
main.py
|
|
@ -1169,7 +1169,7 @@ class FlutterStyleDashboard:
|
|||
min_lines=2,
|
||||
max_lines=3,
|
||||
)
|
||||
|
||||
|
||||
def toggle_edit_mode(_):
|
||||
"""編集モード切替"""
|
||||
old_mode = getattr(self, 'is_detail_edit_mode', False)
|
||||
|
|
@ -1190,15 +1190,7 @@ class FlutterStyleDashboard:
|
|||
validation = validate_invoice_items(normalized_items)
|
||||
if not validation.ok:
|
||||
logging.warning(f"伝票保存バリデーションエラー: {validation.errors}")
|
||||
try:
|
||||
self.page.snack_bar = ft.SnackBar(
|
||||
content=ft.Text(validation.errors[0]),
|
||||
bgcolor=ft.Colors.RED_600,
|
||||
)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
except Exception:
|
||||
pass
|
||||
self._show_snack(validation.errors[0], ft.Colors.RED_600)
|
||||
return
|
||||
|
||||
self.editing_invoice.items = normalized_items
|
||||
|
|
@ -1249,11 +1241,7 @@ class FlutterStyleDashboard:
|
|||
if success:
|
||||
save_succeeded = True
|
||||
logging.info(f"伝票作成成功: {self.editing_invoice.invoice_number}")
|
||||
self.page.snack_bar = ft.SnackBar(
|
||||
content=ft.Text("伝票を保存しました"),
|
||||
bgcolor=ft.Colors.GREEN_600,
|
||||
)
|
||||
self.page.snack_bar.open = True
|
||||
self._show_snack("伝票を保存しました", ft.Colors.GREEN_600)
|
||||
# 一覧を更新して新規作成画面を閉じる
|
||||
self.invoices = self.app_service.invoice.get_recent_invoices(20)
|
||||
logging.info(f"更新後伝票件数: {len(self.invoices)}")
|
||||
|
|
@ -1262,12 +1250,7 @@ class FlutterStyleDashboard:
|
|||
self.update_main_content()
|
||||
else:
|
||||
logging.error(f"伝票作成失敗: {self.editing_invoice.invoice_number}")
|
||||
self.page.snack_bar = ft.SnackBar(
|
||||
content=ft.Text("保存に失敗しました。編集内容を確認してください。"),
|
||||
bgcolor=ft.Colors.RED_600,
|
||||
)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
self._show_snack("保存に失敗しました。編集内容を確認してください。", ft.Colors.RED_600)
|
||||
else:
|
||||
# 更新
|
||||
logging.info(f"=== 伝票更新開 ===")
|
||||
|
|
@ -1285,39 +1268,33 @@ class FlutterStyleDashboard:
|
|||
except Exception as e:
|
||||
logging.error(f"顧客作成失敗(update側): {e}")
|
||||
|
||||
# 既存顧客ならマスタも更新
|
||||
if getattr(self.editing_invoice.customer, "id", 0) > 0:
|
||||
try:
|
||||
self.app_service.customer.update_customer(self.editing_invoice.customer)
|
||||
except Exception as e:
|
||||
logging.warning(f"顧客更新失敗(続行): {e}")
|
||||
|
||||
success = self.app_service.invoice.update_invoice(self.editing_invoice)
|
||||
if success:
|
||||
save_succeeded = True
|
||||
logging.info(f"伝票更新成功: {self.editing_invoice.invoice_number}")
|
||||
self.page.snack_bar = ft.SnackBar(
|
||||
content=ft.Text("伝票を更新しました"),
|
||||
bgcolor=ft.Colors.GREEN_600,
|
||||
)
|
||||
self.page.snack_bar.open = True
|
||||
self._show_snack("伝票を更新しました", ft.Colors.GREEN_600)
|
||||
# 一覧データは更新
|
||||
self.invoices = self.app_service.invoice.get_recent_invoices(20)
|
||||
# 設定により遷移先を変更
|
||||
if not self.stay_on_detail_after_save:
|
||||
self.editing_invoice = None
|
||||
self.current_tab = 0 # 一覧タブに戻る
|
||||
self.update_main_content()
|
||||
else:
|
||||
logging.error(f"伝票更新失敗: {self.editing_invoice.invoice_number}")
|
||||
self.page.snack_bar = ft.SnackBar(
|
||||
content=ft.Text("更新に失敗しました。編集内容を確認してください。"),
|
||||
bgcolor=ft.Colors.RED_600,
|
||||
)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
self._show_snack("更新に失敗しました。編集内容を確認してください。", ft.Colors.RED_600)
|
||||
except Exception as e:
|
||||
logging.error(f"伝票保存エラー: {e}")
|
||||
import traceback
|
||||
logging.error(f"詳細エラー: {traceback.format_exc()}")
|
||||
self.page.snack_bar = ft.SnackBar(
|
||||
content=ft.Text("保存中にエラーが発生しました"),
|
||||
bgcolor=ft.Colors.RED_600,
|
||||
)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
self._show_snack("保存中にエラーが発生しました", ft.Colors.RED_600)
|
||||
save_succeeded = False
|
||||
|
||||
if save_succeeded:
|
||||
|
|
@ -1643,12 +1620,22 @@ class FlutterStyleDashboard:
|
|||
self.page.update()
|
||||
except Exception as e:
|
||||
logging.warning(f"TimePicker open error: {e}")
|
||||
|
||||
def _show_snack(self, message: str, color=ft.Colors.BLUE_GREY_800):
|
||||
try:
|
||||
self.page.snack_bar = ft.SnackBar(content=ft.Text(message), bgcolor=color)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
except Exception as e:
|
||||
logging.warning(f"snack_bar表示失敗: {e}")
|
||||
def create_new_customer_screen(self) -> ft.Container:
|
||||
"""新規顧客登録画面"""
|
||||
name_field = ft.TextField(label="顧客名(略称)")
|
||||
formal_name_field = ft.TextField(label="正式名称")
|
||||
address_field = ft.TextField(label="住所")
|
||||
phone_field = ft.TextField(label="電話番号")
|
||||
"""新規/既存顧客登録・編集画面"""
|
||||
editing_customer = getattr(self, "editing_customer_for_form", None)
|
||||
|
||||
name_field = ft.TextField(label="顧客名(略称)", value=getattr(editing_customer, "name", ""))
|
||||
formal_name_field = ft.TextField(label="正式名称", value=getattr(editing_customer, "formal_name", ""))
|
||||
address_field = ft.TextField(label="住所", value=getattr(editing_customer, "address", ""))
|
||||
phone_field = ft.TextField(label="電話番号", value=getattr(editing_customer, "phone", ""))
|
||||
|
||||
def save_customer(_):
|
||||
name = (name_field.value or "").strip()
|
||||
|
|
@ -1656,23 +1643,38 @@ class FlutterStyleDashboard:
|
|||
address = (address_field.value or "").strip()
|
||||
phone = (phone_field.value or "").strip()
|
||||
if not name or not formal_name:
|
||||
try:
|
||||
self.page.snack_bar = ft.SnackBar(content=ft.Text("顧客名と正式名称は必須です"), bgcolor=ft.Colors.RED_600)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
except Exception:
|
||||
pass
|
||||
self._show_snack("顧客名と正式名称は必須です", ft.Colors.RED_600)
|
||||
return
|
||||
|
||||
# 既存編集か新規かで分岐
|
||||
if editing_customer and getattr(editing_customer, "id", 0) > 0:
|
||||
try:
|
||||
editing_customer.name = name
|
||||
editing_customer.formal_name = formal_name
|
||||
editing_customer.address = address
|
||||
editing_customer.phone = phone
|
||||
self.app_service.customer.update_customer(editing_customer)
|
||||
self.customers = self.app_service.customer.get_all_customers()
|
||||
self.selected_customer = editing_customer
|
||||
if self.editing_invoice:
|
||||
self.editing_invoice.customer = editing_customer
|
||||
self._show_snack("顧客を更新しました", ft.Colors.GREEN_600)
|
||||
self.editing_customer_for_form = None
|
||||
self.is_customer_picker_open = False
|
||||
self.is_new_customer_form_open = False
|
||||
self.update_main_content()
|
||||
return
|
||||
except Exception as e:
|
||||
logging.error(f"顧客更新エラー: {e}")
|
||||
self._show_snack("保存に失敗しました", ft.Colors.RED_600)
|
||||
return
|
||||
|
||||
# 新規登録フロー
|
||||
try:
|
||||
new_customer = self.app_service.customer.create_customer(name, formal_name, address, phone)
|
||||
except Exception as e:
|
||||
logging.error(f"顧客登録エラー: {e}")
|
||||
try:
|
||||
self.page.snack_bar = ft.SnackBar(content=ft.Text("保存に失敗しました"), bgcolor=ft.Colors.RED_600)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
except Exception:
|
||||
pass
|
||||
self._show_snack("保存に失敗しました", ft.Colors.RED_600)
|
||||
return
|
||||
|
||||
# create_customer がID(int)を返す場合にも対応
|
||||
|
|
@ -1701,17 +1703,14 @@ class FlutterStyleDashboard:
|
|||
logging.info(f"新規顧客登録: {created_customer_obj.formal_name}")
|
||||
self.is_customer_picker_open = False
|
||||
self.is_new_customer_form_open = False
|
||||
self.editing_customer_for_form = None
|
||||
self.update_main_content()
|
||||
else:
|
||||
logging.error("新規顧客登録失敗")
|
||||
try:
|
||||
self.page.snack_bar = ft.SnackBar(content=ft.Text("保存に失敗しました"), bgcolor=ft.Colors.RED_600)
|
||||
self.page.snack_bar.open = True
|
||||
self.page.update()
|
||||
except Exception:
|
||||
pass
|
||||
self._show_snack("保存に失敗しました", ft.Colors.RED_600)
|
||||
|
||||
def cancel(_):
|
||||
self.editing_customer_for_form = None
|
||||
self.is_new_customer_form_open = False
|
||||
self.update_main_content()
|
||||
|
||||
|
|
@ -1720,7 +1719,7 @@ class FlutterStyleDashboard:
|
|||
ft.Container(
|
||||
content=ft.Row([
|
||||
ft.IconButton(ft.Icons.ARROW_BACK, on_click=cancel),
|
||||
ft.Text("新規顧客登録", size=18, weight=ft.FontWeight.BOLD),
|
||||
ft.Text("顧客登録/編集", size=18, weight=ft.FontWeight.BOLD),
|
||||
]),
|
||||
padding=ft.Padding.all(15),
|
||||
bgcolor=ft.Colors.BLUE_GREY,
|
||||
|
|
@ -1782,6 +1781,13 @@ class FlutterStyleDashboard:
|
|||
self.is_customer_picker_open = False
|
||||
self.update_main_content()
|
||||
|
||||
def open_edit_customer(c: Customer):
|
||||
# 長押しで顧客を編集
|
||||
self.editing_customer_for_form = c
|
||||
self.is_new_customer_form_open = True
|
||||
self.is_customer_picker_open = False
|
||||
self.update_main_content()
|
||||
|
||||
customer_cards = []
|
||||
for c in customers:
|
||||
customer_cards.append(
|
||||
|
|
@ -1794,6 +1800,7 @@ class FlutterStyleDashboard:
|
|||
)
|
||||
),
|
||||
on_click=lambda _, cu=c: on_pick(cu),
|
||||
on_long_press=lambda _, cu=c: open_edit_customer(cu),
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -354,12 +354,15 @@ class InvoiceRepository:
|
|||
# 伝票基本情報を更新
|
||||
cursor.execute('''
|
||||
UPDATE invoices
|
||||
SET document_type = ?, customer_id = ?, date = ?,
|
||||
invoice_number = ?, notes = ?, pdf_generated_at = ?
|
||||
SET document_type = ?, customer_id = ?, customer_name = ?, customer_address = ?, customer_phone = ?,
|
||||
date = ?, invoice_number = ?, notes = ?, pdf_generated_at = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE uuid = ?
|
||||
''', (
|
||||
invoice.document_type.value,
|
||||
invoice.customer.id if hasattr(invoice.customer, 'id') else None,
|
||||
getattr(invoice.customer, 'formal_name', None),
|
||||
getattr(invoice.customer, 'address', None),
|
||||
getattr(invoice.customer, 'phone', None),
|
||||
invoice.date.isoformat(),
|
||||
invoice.invoice_number,
|
||||
invoice.notes,
|
||||
|
|
|
|||
Loading…
Reference in a new issue