payDeserialize function

PayDataModel payDeserialize(
  1. String tabString
)

Parses the tab-separated tabString into a PayDataModel.

Implementation

PayDataModel payDeserialize(String tabString) {
  final data = tabString.split('\t');
  int i = 0;

  String? next() => i < data.length ? data[i++] : null;

  final invoiceId = _parseString(next());
  final paymentsCount = int.parse(next() ?? '0');

  final payments = <Payment>[];

  for (int p = 0; p < paymentsCount; p++) {
    final type = int.parse(next() ?? '0');
    final amount = _parseNumber(next());
    final currencyCode = next() ?? 'EUR';
    final paymentDueDate = _parseString(next());
    final variableSymbol = _parseString(next());
    final constantSymbol = _parseString(next());
    final specificSymbol = _parseString(next());
    final originatorsRefInfo = _parseString(next());
    final paymentNote = _parseString(next());

    // Bank accounts
    final bankAccountsCount = int.parse(next() ?? '0');
    final bankAccounts = <BankAccount>[];
    for (int j = 0; j < bankAccountsCount; j++) {
      final iban = next() ?? '';
      final bic = _parseString(next());
      bankAccounts.add(BankAccount(iban: iban, bic: bic));
    }

    const placeholder = Beneficiary(name: '');

    // Standing order extension - always consumed to keep field alignment
    final standingOrderFlag = next();
    int? soDay;
    int? soMonth;
    String? soPeriodicity;
    String? soLastDate;
    if (standingOrderFlag == '1') {
      soDay = _parseNumber(next())?.toInt();
      soMonth = _parseNumber(next())?.toInt();
      soPeriodicity = _parseString(next());
      soLastDate = _parseString(next());
    }

    // Direct debit extension - always consumed to keep field alignment
    final directDebitFlag = next();
    int? ddScheme;
    int? ddType;
    String? ddVarSymbol;
    String? ddSpecSymbol;
    String? ddOriginatorsRef;
    String? ddMandateId;
    String? ddCreditorId;
    String? ddContractId;
    double? ddMaxAmount;
    String? ddValidTill;
    if (directDebitFlag == '1') {
      ddScheme = _parseNumber(next())?.toInt();
      ddType = _parseNumber(next())?.toInt();
      ddVarSymbol = _parseString(next());
      ddSpecSymbol = _parseString(next());
      ddOriginatorsRef = _parseString(next());
      ddMandateId = _parseString(next());
      ddCreditorId = _parseString(next());
      ddContractId = _parseString(next());
      ddMaxAmount = _parseNumber(next());
      ddValidTill = _parseString(next());
    }

    final Payment payment;
    if (type == PaymentOptions.standingOrder) {
      payment = StandingOrder(
        amount: amount,
        currencyCode: currencyCode,
        paymentDueDate: paymentDueDate,
        variableSymbol: variableSymbol,
        constantSymbol: constantSymbol,
        specificSymbol: specificSymbol,
        originatorsReferenceInformation: originatorsRefInfo,
        paymentNote: paymentNote,
        bankAccounts: bankAccounts,
        beneficiary: placeholder,
        day: soDay,
        month: soMonth,
        periodicity: soPeriodicity ?? '',
        lastDate: soLastDate,
      );
    } else if (type == PaymentOptions.directDebit) {
      payment = DirectDebit(
        amount: amount,
        currencyCode: currencyCode,
        paymentDueDate: paymentDueDate,
        variableSymbol: variableSymbol,
        constantSymbol: constantSymbol,
        specificSymbol: specificSymbol,
        originatorsReferenceInformation: originatorsRefInfo,
        paymentNote: paymentNote,
        bankAccounts: bankAccounts,
        beneficiary: placeholder,
        directDebitScheme: ddScheme,
        directDebitType: ddType,
        ddVariableSymbol: ddVarSymbol,
        ddSpecificSymbol: ddSpecSymbol,
        ddOriginatorsReferenceInformation: ddOriginatorsRef,
        mandateId: ddMandateId,
        creditorId: ddCreditorId,
        contractId: ddContractId,
        maxAmount: ddMaxAmount,
        validTillDate: ddValidTill,
      );
    } else {
      payment = PaymentOrder(
        amount: amount,
        currencyCode: currencyCode,
        paymentDueDate: paymentDueDate,
        variableSymbol: variableSymbol,
        constantSymbol: constantSymbol,
        specificSymbol: specificSymbol,
        originatorsReferenceInformation: originatorsRefInfo,
        paymentNote: paymentNote,
        bankAccounts: bankAccounts,
        beneficiary: placeholder,
      );
    }

    payments.add(payment);
  }

  // Beneficiary block - one entry per payment after all payment blocks
  for (int p = 0; p < paymentsCount; p++) {
    final name = next() ?? '';
    final street = _parseString(next());
    final city = _parseString(next());
    final beneficiary = Beneficiary(name: name, street: street, city: city);
    payments[p] = _withBeneficiary(payments[p], beneficiary);
  }

  return PayDataModel(invoiceId: invoiceId, payments: payments);
}