Explorar el Código

fix #19407 优化币别汇率传值

chengc hace 1 semana
padre
commit
df36b6dbb0

+ 26 - 7
lib/features/expense/expense_api.dart

@@ -94,10 +94,16 @@ class CustomerItem {
 class CurrencyItem {
   final String curId;
   final String name;
-  const CurrencyItem({required this.curId, required this.name});
+  final double excRto;
+  const CurrencyItem({
+    required this.curId,
+    required this.name,
+    this.excRto = 1.0,
+  });
   factory CurrencyItem.fromJson(Map<String, dynamic> json) => CurrencyItem(
     curId: json['curId'] as String? ?? '',
     name: json['name'] as String? ?? '',
+    excRto: (json['excRto'] as num?)?.toDouble() ?? 1.0,
   );
 }
 
@@ -134,7 +140,10 @@ class EmployeeItem {
 
 class ExpenseApi {
   final ApiClient _client;
-  final _cache = ApiCache(keyPrefix: '${HostAppChannel.sn}_${HostAppChannel.compNo}_${HostAppChannel.usr}');
+  final _cache = ApiCache(
+    keyPrefix:
+        '${HostAppChannel.sn}_${HostAppChannel.compNo}_${HostAppChannel.usr}',
+  );
   ExpenseApi(this._client);
 
   /// 清除所有基础资料缓存(picker 下拉刷新时调用)。
@@ -591,8 +600,11 @@ class ExpenseApi {
       '/OA/GetExpenseSubordinateReport',
       queryParameters: params,
     );
-    final list = (response.data as List<dynamic>?)
-            ?.map((e) => SubordinateReportItem.fromJson(e as Map<String, dynamic>))
+    final list =
+        (response.data as List<dynamic>?)
+            ?.map(
+              (e) => SubordinateReportItem.fromJson(e as Map<String, dynamic>),
+            )
             .toList() ??
         [];
     return list;
@@ -618,9 +630,16 @@ class ExpenseApi {
   }
 
   /// 审核过程明细
-  Future<List<Map<String, dynamic>>> getAuditTrail(String billId, String billNo) async {
-    final response = await _client.get('/OA/GetAuditTrail', queryParameters: {'billId': billId, 'billNo': billNo});
-    final list = (response.data as List<dynamic>?)?.cast<Map<String, dynamic>>() ?? [];
+  Future<List<Map<String, dynamic>>> getAuditTrail(
+    String billId,
+    String billNo,
+  ) async {
+    final response = await _client.get(
+      '/OA/GetAuditTrail',
+      queryParameters: {'billId': billId, 'billNo': billNo},
+    );
+    final list =
+        (response.data as List<dynamic>?)?.cast<Map<String, dynamic>>() ?? [];
     return list;
   }
 

+ 20 - 7
lib/features/expense/expense_create_controller.dart

@@ -36,12 +36,16 @@ class ExpenseCreateController extends StateNotifier<ExpenseCreateState> {
         ),
       );
 
-  void updateCurrencyCode(String code) {
-    state = state.copyWith(expense: state.expense.copyWith(currencyCode: code));
+  void updateCurrencyCode(String code, double excRto) {
+    state = state.copyWith(
+      expense: state.expense.copyWith(currencyCode: code, excRto: excRto),
+    );
   }
 
   void updateApprovedAmount(double amount) {
-    state = state.copyWith(expense: state.expense.copyWith(approvedAmount: amount));
+    state = state.copyWith(
+      expense: state.expense.copyWith(approvedAmount: amount),
+    );
   }
 
   void updateDetailApprovedAmount(int index, double amount) {
@@ -100,7 +104,9 @@ class ExpenseCreateController extends StateNotifier<ExpenseCreateState> {
   }
 
   void updatePaymentMethod(String method) {
-    state = state.copyWith(expense: state.expense.copyWith(paymentMethod: method));
+    state = state.copyWith(
+      expense: state.expense.copyWith(paymentMethod: method),
+    );
   }
 
   void updateRemark(String remark) {
@@ -108,11 +114,15 @@ class ExpenseCreateController extends StateNotifier<ExpenseCreateState> {
   }
 
   void setGenerateVoucher(bool value) {
-    state = state.copyWith(expense: state.expense.copyWith(isGenerateVoucher: value));
+    state = state.copyWith(
+      expense: state.expense.copyWith(isGenerateVoucher: value),
+    );
   }
 
   void updateDept(String deptId, String deptName) {
-    state = state.copyWith(expense: state.expense.copyWith(deptId: deptId, deptName: deptName));
+    state = state.copyWith(
+      expense: state.expense.copyWith(deptId: deptId, deptName: deptName),
+    );
   }
 
   void addDetail(ExpenseDetailModel detail) {
@@ -192,7 +202,10 @@ class ExpenseCreateController extends StateNotifier<ExpenseCreateState> {
 }
 
 final expenseCreateProvider = StateNotifierProvider.autoDispose
-    .family<ExpenseCreateController, ExpenseCreateState, String?>((ref, editId) {
+    .family<ExpenseCreateController, ExpenseCreateState, String?>((
+      ref,
+      editId,
+    ) {
       final api = ref.watch(expenseApiProvider);
       return ExpenseCreateController(api);
     });

+ 5 - 8
lib/features/expense/expense_create_page.dart

@@ -1,4 +1,4 @@
-import 'dart:async';
+import 'dart:async';
 import 'dart:io';
 
 import 'package:flutter/material.dart';
@@ -394,7 +394,7 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
         'USR': HostAppChannel.usr,
         'REM': expense.remark,
         'CUR_ID': expense.currencyCode,
-        'EXC_RTO': 1,
+        'EXC_RTO': expense.excRto,
         'REASON': expense.purpose,
         'VOH_ID': expense.isGenerateVoucher ? 'T' : 'F',
       },
@@ -607,7 +607,7 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
               : null,
           hint: l10n.get('selectCurrency'),
           onTap: () => _showCurrencyPicker(controller, expense.currencyCode),
-          onClear: () => controller.updateCurrencyCode(''),
+          onClear: () => controller.updateCurrencyCode('', 1.0),
         ),
         const SizedBox(height: 16),
         Row(
@@ -1125,10 +1125,7 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
           await ExpenseCreateController.deleteDraft();
           if (mounted) {
             LoadingDialog.hide(context);
-            TDToast.showSuccess(
-              l10n.get('submitSuccess'),
-              context: context,
-            );
+            TDToast.showSuccess(l10n.get('submitSuccess'), context: context);
             GoRouter.of(context).go('/expense/list');
           }
         } catch (e) {
@@ -1295,7 +1292,7 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
           final i = s[0] as int;
           if (i >= 0 && i < codes.length) {
             Navigator.of(context).pop();
-            controller.updateCurrencyCode(codes[i]);
+            controller.updateCurrencyCode(codes[i], _currencies[i].excRto);
           }
         }
       },

+ 10 - 10
lib/features/expense/expense_edit_page.dart

@@ -1,4 +1,4 @@
-import 'dart:async';
+import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
@@ -116,7 +116,10 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
         _selectedDeptId = expense.deptId;
         _selectedDeptName = expense.deptName;
         _selEmployee = expense.applicantId.isNotEmpty
-            ? EmployeeItem(salNo: expense.applicantId, name: expense.applicantName)
+            ? EmployeeItem(
+                salNo: expense.applicantId,
+                name: expense.applicantName,
+              )
             : null;
         _purposeController.text = expense.purpose;
         _remarkController.text = expense.remark;
@@ -201,10 +204,10 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
     });
   }
 
-  void _updateCurrencyCode(String code) {
+  void _updateCurrencyCode(String code, [double excRto = 1.0]) {
     if (_expense == null) return;
     setState(() {
-      _expense = _expense!.copyWith(currencyCode: code);
+      _expense = _expense!.copyWith(currencyCode: code, excRto: excRto);
     });
   }
 
@@ -307,7 +310,7 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
         'USR': HostAppChannel.usr,
         'REM': expense.remark,
         'CUR_ID': expense.currencyCode,
-        'EXC_RTO': 1,
+        'EXC_RTO': expense.excRto,
         'REASON': expense.purpose,
         'VOH_ID': expense.isGenerateVoucher ? 'T' : 'F',
       },
@@ -967,7 +970,7 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
           final i = s[0] as int;
           if (i >= 0 && i < codes.length) {
             Navigator.of(context).pop();
-            _updateCurrencyCode(codes[i]);
+            _updateCurrencyCode(codes[i], _currencies[i].excRto);
           }
         }
       },
@@ -1050,10 +1053,7 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
           await api.submit(data);
           if (mounted) {
             LoadingDialog.hide(context);
-            TDToast.showSuccess(
-              l10n.get('submitSuccess'),
-              context: context,
-            );
+            TDToast.showSuccess(l10n.get('submitSuccess'), context: context);
             WidgetsBinding.instance.addPostFrameCallback((_) {
               if (mounted) GoRouter.of(context).pop(true);
             });

+ 15 - 3
lib/features/expense/expense_model.dart

@@ -10,6 +10,7 @@ class ExpenseModel {
   final String deptId;
   final String deptName;
   final String currencyCode;
+  final double excRto;
   final bool isGenerateVoucher;
   final String voucherNo;
   final double approvedAmount;
@@ -54,6 +55,7 @@ class ExpenseModel {
     this.deptId = '',
     this.deptName = '',
     this.currencyCode = '',
+    this.excRto = 1.0,
     this.isGenerateVoucher = true,
     this.voucherNo = '',
     this.approvedAmount = 0.0,
@@ -98,15 +100,22 @@ class ExpenseModel {
           json['applicantName'] as String? ?? json['usrNo'] as String? ?? '',
       deptId: json['dept'] as String? ?? '',
       deptName: json['deptName'] as String? ?? json['dept'] as String? ?? '',
-      currencyCode: (json['curId'] as String?) ?? (json['currencyCode'] as String?) ?? '',
-      isGenerateVoucher: (json['vohId'] as String?) == 'T' || json['isGenerateVoucher'] == true,
+      currencyCode:
+          (json['curId'] as String?) ?? (json['currencyCode'] as String?) ?? '',
+      excRto: (json['excRto'] as num?)?.toDouble() ?? 1.0,
+      isGenerateVoucher:
+          (json['vohId'] as String?) == 'T' ||
+          json['isGenerateVoucher'] == true,
       voucherNo: json['vohNo'] as String? ?? '',
       approvedAmount: (json['approvedAmount'] as num?)?.toDouble() ?? 0.0,
       totalAmount: (json['totalAmount'] as num?)?.toDouble() ?? 0.0,
       totalAmtnSh: (json['totalAmtnSh'] as num?)?.toDouble() ?? 0.0,
       purpose: json['reason'] as String? ?? json['purpose'] as String? ?? '',
       remark: (json['rem'] as String?) ?? (json['remark'] as String?) ?? '',
-      paymentMethod: (json['payId'] as String?) ?? (json['paymentMethod'] as String?) ?? '',
+      paymentMethod:
+          (json['payId'] as String?) ??
+          (json['paymentMethod'] as String?) ??
+          '',
       isInvoiceVerified: json['isInvoiceVerified'] as bool? ?? false,
       isTaxIdMatched: json['isTaxIdMatched'] as bool? ?? false,
       isCategoryCompliant: json['isCategoryCompliant'] as bool? ?? false,
@@ -167,6 +176,7 @@ class ExpenseModel {
     'deptId': deptId,
     'deptName': deptName,
     'currencyCode': currencyCode,
+    'excRto': excRto,
     'isGenerateVoucher': isGenerateVoucher,
     'voucherNo': voucherNo,
     'approvedAmount': approvedAmount,
@@ -208,6 +218,7 @@ class ExpenseModel {
     String? deptId,
     String? deptName,
     String? currencyCode,
+    double? excRto,
     bool? isGenerateVoucher,
     String? voucherNo,
     double? approvedAmount,
@@ -248,6 +259,7 @@ class ExpenseModel {
       deptId: deptId ?? this.deptId,
       deptName: deptName ?? this.deptName,
       currencyCode: currencyCode ?? this.currencyCode,
+      excRto: excRto ?? this.excRto,
       isGenerateVoucher: isGenerateVoucher ?? this.isGenerateVoucher,
       voucherNo: voucherNo ?? this.voucherNo,
       approvedAmount: approvedAmount ?? this.approvedAmount,