func (t *TransactionTag) Unmarshal(value []byte) error {
	elements, err := extractTagElements(value)
	if err != nil {
		return err
	}
	if len(elements) != 2 {
		return fmt.Errorf("%T: Malformed marshaled value", t)
	}
	t.Tag = string(elements[0])
	buf := bytes.NewBuffer(elements[1])
	dateBytes := buf.Next(6)
	date, err := parseDate(dateBytes, time.Now().Year())
	if err != nil {
		return errors.WithMessage(err, "unmarshal transaction tag: parsing valuta date")
	}
	t.ValutaDate = domain.NewShortDate(date)
	r, _, err := buf.ReadRune()
	if err != nil {
		return err
	}
	if unicode.IsDigit(r) {
		buf.UnreadRune()
		dateBytes = buf.Next(4)
		date, err = parseDate(dateBytes, t.ValutaDate.Year())
		if err != nil {
			return errors.WithMessage(err, "unmarshal transaction tag: parsing booking date")
		}
		t.BookingDate = domain.NewShortDate(date)
		monthDiff := int(math.Abs(float64(t.ValutaDate.Month() - t.BookingDate.Month())))
		if monthDiff > 1 {
			t.BookingDate = domain.NewShortDate(t.BookingDate.AddDate(1, 0, 0))
		}
	}
	var runes []rune
	for {
		r, _, err := buf.ReadRune()
		if err != nil {
			return err
		}
		runes = append(runes, r)
		if unicode.IsDigit(r) {
			buf.UnreadRune()
			runes = runes[:len(runes)-1]
			if len(runes) == 3 {
				t.DebitCreditIndicator = string(runes[:2])
				t.CurrencyKind = string(runes[2:])
			} else if len(runes) == 2 {
				t.DebitCreditIndicator = string(runes[:1])
				t.CurrencyKind = string(runes[1:])
			} else if len(runes) == 1 {
				t.DebitCreditIndicator = string(runes)
			} else {
				return fmt.Errorf("%T: Malformed marshaled value", t)
			}
			break
		}
	}
	amountBytes, err := buf.ReadBytes('N')
	if err != nil {
		return err
	}
	amountBytes = bytes.Replace(amountBytes[:len(amountBytes)-1], []byte(","), []byte("."), 1)
	amount, err := strconv.ParseFloat(string(amountBytes), 64)
	if err != nil {
		return errors.Wrap(err, "MT940 Transaction tag: error unmarshaling amount")
	}
	t.Amount = amount
	t.BookingKey = string(buf.Next(3))
	remaining := buf.String()
	addInfSepIdx := strings.Index(remaining, "\r\n/")
	doubleSlashIdx := strings.Index(remaining, "//")

	if doubleSlashIdx != -1 && addInfSepIdx != -1 {
		t.Reference = remaining[:doubleSlashIdx]
		if doubleSlashIdx < addInfSepIdx {
			t.BankReference = remaining[doubleSlashIdx+2 : addInfSepIdx]
			t.AdditionalInformation = remaining[addInfSepIdx+3:]
		} else {
			// The only valid case in the FINTS30 documentation in the other
			// one, but the data we receive are sometimes formatted like that
			// :(
			t.BankReference = remaining[addInfSepIdx+3 : doubleSlashIdx]
			t.AdditionalInformation = remaining[doubleSlashIdx+2:]
		}
	} else {
		t.Reference = remaining
		if doubleSlashIdx != -1 {
			t.Reference = remaining[:doubleSlashIdx]
			t.BankReference = remaining[doubleSlashIdx+2:]
		}
		if addInfSepIdx != -1 {
			t.Reference = remaining[:addInfSepIdx]
			t.AdditionalInformation = remaining[addInfSepIdx+3:]
		}
	}
	return nil
}
// Unmarshal unmarshals value into t
Unmarshal unmarshals value into t
// Unmarshal unmarshals value into t
func (t *TransactionTag) Unmarshal(value []byte) error {
	elements, err := extractTagElements(value)
	if err != nil {
		return err
	}
	if len(elements) != 2 {
		return fmt.Errorf("%T: Malformed marshaled value", t)
	}
	t.Tag = string(elements[0])
	buf := bytes.NewBuffer(elements[1])
	dateBytes := buf.Next(6)
	date, err := parseDate(dateBytes, time.Now().Year())
	if err != nil {
		return errors.WithMessage(err, "unmarshal transaction tag: parsing valuta date")
	}
	t.ValutaDate = domain.NewShortDate(date)
	r, _, err := buf.ReadRune()
	if err != nil {
		return err
	}
	if unicode.IsDigit(r) {
		buf.UnreadRune()
		dateBytes = buf.Next(4)
		date, err = parseDate(dateBytes, t.ValutaDate.Year())
		if err != nil {
			return errors.WithMessage(err, "unmarshal transaction tag: parsing booking date")
		}
		t.BookingDate = domain.NewShortDate(date)
		monthDiff := int(math.Abs(float64(t.ValutaDate.Month() - t.BookingDate.Month())))
		if monthDiff > 1 {
			t.BookingDate = domain.NewShortDate(t.BookingDate.AddDate(1, 0, 0))
		}
	}
	var runes []rune
	for {
		r, _, err := buf.ReadRune()
		if err != nil {
			return err
		}
		runes = append(runes, r)
		if unicode.IsDigit(r) {
			buf.UnreadRune()
			runes = runes[:len(runes)-1]
			if len(runes) == 3 {
				t.DebitCreditIndicator = string(runes[:2])
				t.CurrencyKind = string(runes[2:])
			} else if len(runes) == 2 {
				t.DebitCreditIndicator = string(runes[:1])
				t.CurrencyKind = string(runes[1:])
			} else if len(runes) == 1 {
				t.DebitCreditIndicator = string(runes)
			} else {
				return fmt.Errorf("%T: Malformed marshaled value", t)
			}
			break
		}
	}
	amountBytes, err := buf.ReadBytes('N')
	if err != nil {
		return err
	}
	amountBytes = bytes.Replace(amountBytes[:len(amountBytes)-1], []byte(","), []byte("."), 1)
	amount, err := strconv.ParseFloat(string(amountBytes), 64)
	if err != nil {
		return errors.Wrap(err, "MT940 Transaction tag: error unmarshaling amount")
	}
	t.Amount = amount
	t.BookingKey = string(buf.Next(3))
	remaining := buf.String()
	addInfSepIdx := strings.Index(remaining, "\r\n/")
	doubleSlashIdx := strings.Index(remaining, "//")
	if doubleSlashIdx != -1 && addInfSepIdx != -1 {
		t.Reference = remaining[:doubleSlashIdx]
		if doubleSlashIdx < addInfSepIdx {
			t.BankReference = remaining[doubleSlashIdx+2 : addInfSepIdx]
			t.AdditionalInformation = remaining[addInfSepIdx+3:]
		} else {
			t.BankReference = remaining[addInfSepIdx+3 : doubleSlashIdx]
			t.AdditionalInformation = remaining[doubleSlashIdx+2:]
		}
	} else {
		t.Reference = remaining
		if doubleSlashIdx != -1 {
			t.Reference = remaining[:doubleSlashIdx]
			t.BankReference = remaining[doubleSlashIdx+2:]
		}
		if addInfSepIdx != -1 {
			t.Reference = remaining[:addInfSepIdx]
			t.AdditionalInformation = remaining[addInfSepIdx+3:]
		}
	}
	return nil
}
func ( t * TransactionTag ) Unmarshal ( value [ ] byte ) error { elements , err := extractTagElements ( value ) if err != nil { return err } if len ( elements ) != 2 { return fmt . Errorf ( " " , t ) } t . Tag = string ( elements [ 0 ] ) buf := bytes . NewBuffer ( elements [ 1 ] ) dateBytes := buf . Next ( 6 ) date , err := parseDate ( dateBytes , time . Now ( ) . Year ( ) ) if err != nil { return errors . WithMessage ( err , " " ) } t . ValutaDate = domain . NewShortDate ( date ) r , _ , err := buf . ReadRune ( ) if err != nil { return err } if unicode . IsDigit ( r ) { buf . UnreadRune ( ) dateBytes = buf . Next ( 4 ) date , err = parseDate ( dateBytes , t . ValutaDate . Year ( ) ) if err != nil { return errors . WithMessage ( err , " " ) } t . BookingDate = domain . NewShortDate ( date ) monthDiff := int ( math . Abs ( float64 ( t . ValutaDate . Month ( ) - t . BookingDate . Month ( ) ) ) ) if monthDiff > 1 { t . BookingDate = domain . NewShortDate ( t . BookingDate . AddDate ( 1 , 0 , 0 ) ) } } var runes [ ] rune for { r , _ , err := buf . ReadRune ( ) if err != nil { return err } runes = append ( runes , r ) if unicode . IsDigit ( r ) { buf . UnreadRune ( ) runes = runes [ : len ( runes ) - 1 ] if len ( runes ) == 3 { t . DebitCreditIndicator = string ( runes [ : 2 ] ) t . CurrencyKind = string ( runes [ 2 : ] ) } else if len ( runes ) == 2 { t . DebitCreditIndicator = string ( runes [ : 1 ] ) t . CurrencyKind = string ( runes [ 1 : ] ) } else if len ( runes ) == 1 { t . DebitCreditIndicator = string ( runes ) } else { return fmt . Errorf ( " " , t ) } break } } amountBytes , err := buf . ReadBytes ( 'N' ) if err != nil { return err } amountBytes = bytes . Replace ( amountBytes [ : len ( amountBytes ) - 1 ] , [ ] byte ( " " ) , [ ] byte ( " " ) , 1 ) amount , err := strconv . ParseFloat ( string ( amountBytes ) , 64 ) if err != nil { return errors . Wrap ( err , " " ) } t . Amount = amount t . BookingKey = string ( buf . Next ( 3 ) ) remaining := buf . String ( ) addInfSepIdx := strings . Index ( remaining , " \r \n " ) doubleSlashIdx := strings . Index ( remaining , " " ) if doubleSlashIdx != - 1 && addInfSepIdx != - 1 { t . Reference = remaining [ : doubleSlashIdx ] if doubleSlashIdx < addInfSepIdx { t . BankReference = remaining [ doubleSlashIdx + 2 : addInfSepIdx ] t . AdditionalInformation = remaining [ addInfSepIdx + 3 : ] } else { t . BankReference = remaining [ addInfSepIdx + 3 : doubleSlashIdx ] t . AdditionalInformation = remaining [ doubleSlashIdx + 2 : ] } } else { t . Reference = remaining if doubleSlashIdx != - 1 { t . Reference = remaining [ : doubleSlashIdx ] t . BankReference = remaining [ doubleSlashIdx + 2 : ] } if addInfSepIdx != - 1 { t . Reference = remaining [ : addInfSepIdx ] t . AdditionalInformation = remaining [ addInfSepIdx + 3 : ] } } return nil }
Unmarshal unmarshals value into t
Unmarshal unmarshals value into t
// The only valid case in the FINTS30 documentation in the other // one, but the data we receive are sometimes formatted like that // :(