From 574b40fe9f6990de71e97a860749c831f76d8c04 Mon Sep 17 00:00:00 2001 From: Stephan D Date: Fri, 5 Dec 2025 05:17:14 +0100 Subject: [PATCH] fixed payment methods serialization deserialization --- api/pkg/model/payment.go | 71 +++++++++++++++++++ .../lib/provider/recipient/pmethods.dart | 1 - .../lib/pages/address_book/form/page.dart | 43 +++++++---- 3 files changed, 100 insertions(+), 15 deletions(-) diff --git a/api/pkg/model/payment.go b/api/pkg/model/payment.go index 51be177..27e255c 100644 --- a/api/pkg/model/payment.go +++ b/api/pkg/model/payment.go @@ -1,6 +1,7 @@ package model import ( + "bytes" "encoding/json" "fmt" @@ -71,3 +72,73 @@ type PaymentMethod struct { Data bson.Raw `bson:"data" json:"data"` IsMain bool `bson:"isMain" json:"isMain"` } + +type paymentMethodJSON struct { + PermissionBound `json:",inline"` + Describable `json:",inline"` + + RecipientRef primitive.ObjectID `json:"recipientRef"` + Type PaymentType `json:"type"` + Data json.RawMessage `json:"data"` + IsMain bool `json:"isMain"` +} + +func (m PaymentMethod) MarshalJSON() ([]byte, error) { + var marshaledData json.RawMessage + + if len(m.Data) > 0 { + var data bson.M + if err := bson.Unmarshal(m.Data, &data); err != nil { + return nil, err + } + if data != nil { + b, err := json.Marshal(data) + if err != nil { + return nil, err + } + marshaledData = b + } + } + + payload := paymentMethodJSON{ + PermissionBound: m.PermissionBound, + Describable: m.Describable, + RecipientRef: m.RecipientRef, + Type: m.Type, + Data: marshaledData, + IsMain: m.IsMain, + } + + return json.Marshal(payload) +} + +func (m *PaymentMethod) UnmarshalJSON(data []byte) error { + var payload paymentMethodJSON + if err := json.Unmarshal(data, &payload); err != nil { + return err + } + + m.PermissionBound = payload.PermissionBound + m.Describable = payload.Describable + m.RecipientRef = payload.RecipientRef + m.Type = payload.Type + m.IsMain = payload.IsMain + + if len(payload.Data) == 0 || bytes.Equal(payload.Data, []byte("null")) { + m.Data = nil + return nil + } + + var rawData map[string]any + if err := json.Unmarshal(payload.Data, &rawData); err != nil { + return err + } + + raw, err := bson.Marshal(rawData) + if err != nil { + return err + } + + m.Data = raw + return nil +} diff --git a/frontend/pshared/lib/provider/recipient/pmethods.dart b/frontend/pshared/lib/provider/recipient/pmethods.dart index 23dff1f..a4ecc87 100644 --- a/frontend/pshared/lib/provider/recipient/pmethods.dart +++ b/frontend/pshared/lib/provider/recipient/pmethods.dart @@ -71,7 +71,6 @@ class PaymentMethodsProvider extends GenericProvider { ).toDTO().toJson(), ); - Future makeMain(PaymentMethod method) { // TODO: create separate backend method to manage main payment method final updates = >[]; diff --git a/frontend/pweb/lib/pages/address_book/form/page.dart b/frontend/pweb/lib/pages/address_book/form/page.dart index 29a151e..74c523f 100644 --- a/frontend/pweb/lib/pages/address_book/form/page.dart +++ b/frontend/pweb/lib/pages/address_book/form/page.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; + import 'package:provider/provider.dart'; import 'package:pshared/models/payment/methods/data.dart'; @@ -14,11 +16,11 @@ import 'package:pshared/provider/recipient/provider.dart'; import 'package:pweb/pages/address_book/form/view.dart'; // import 'package:pweb/services/amplitude.dart'; import 'package:pweb/utils/error/snackbar.dart'; - -import 'package:pweb/generated/i18n/app_localizations.dart'; import 'package:pweb/utils/payment/label.dart'; import 'package:pweb/utils/snackbar.dart'; +import 'package:pweb/generated/i18n/app_localizations.dart'; + class AdressBookRecipientForm extends StatefulWidget { final Recipient? recipient; @@ -71,18 +73,31 @@ class _AdressBookRecipientFormState extends State { Future _doSave() async { final recipients = context.read(); final methods = context.read(); - final recipient = await recipients.create( - name: _nameCtrl.text, - email: _emailCtrl.text, - ); - if (methods.currentObject == null) return recipient; - final data = methods.currentObject!; - await methods.create( - reacipientRef: recipient.id, - name: getPaymentTypeLabel(context, data.type), - data: data.data, - ); - return recipient; + final recipient = widget.recipient == null + ? await recipients.create( + name: _nameCtrl.text, + email: _emailCtrl.text, + ) + : widget.recipient!; + for (final type in _methods.keys) { + final data = _methods[type]!; + final exising = methods.methods.firstWhereOrNull((m) => m.type == type); + if (exising != null) { + await methods.updateMethod(exising.copyWith(data: data)); + } else { + await methods.create( + reacipientRef: recipient.id, + name: getPaymentTypeLabel(context, type), + data: data, + ); + } + await methods.create( + reacipientRef: recipient.id, + name: getPaymentTypeLabel(context, data.type), + data: data, + ); + return recipient; + } } //TODO: Change when registration is ready