From 50aa460064d6e47318122b0a8ebe155406cbedd3 Mon Sep 17 00:00:00 2001 From: joe Date: Mon, 23 Feb 2026 20:22:18 +0900 Subject: [PATCH] =?UTF-8?q?=E9=A1=A7=E5=AE=A2=E5=8F=82=E7=85=A7=E9=95=B7?= =?UTF-8?q?=E6=8A=BC=E3=81=97=E3=81=A7=E7=B7=A8=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 131 +++++++++++++++++++++------------------ services/repositories.py | 7 ++- 2 files changed, 74 insertions(+), 64 deletions(-) diff --git a/main.py b/main.py index c3dc3a0..b6caa1d 100644 --- a/main.py +++ b/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), ) ) diff --git a/services/repositories.py b/services/repositories.py index 8ab4ef0..486cd42 100644 --- a/services/repositories.py +++ b/services/repositories.py @@ -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,