Partly resolves issue #86 Reviewed-on: #90 Co-authored-by: alfred-mk <alfredmwaik@gmail.com> Co-committed-by: alfred-mk <alfredmwaik@gmail.com>
		
			
				
	
	
		
			617 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			617 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package application
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"git.defalsify.org/vise.git/db"
 | |
| 	"git.defalsify.org/vise.git/lang"
 | |
| 	"git.defalsify.org/vise.git/resource"
 | |
| 	"git.grassecon.net/grassrootseconomics/common/person"
 | |
| 	storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
 | |
| )
 | |
| 
 | |
| // SaveFirstname updates the first name in the gdbm with the provided input.
 | |
| func (h *MenuHandlers) SaveFirstname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var err error
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 	firstName := string(input)
 | |
| 
 | |
| 	store := h.userdataStore
 | |
| 	logdb := h.logDb
 | |
| 
 | |
| 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 | |
| 	flag_firstname_set, _ := h.flagManager.GetFlag("flag_firstname_set")
 | |
| 
 | |
| 	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
 | |
| 	firstNameSet := h.st.MatchFlag(flag_firstname_set, true)
 | |
| 	if allowUpdate {
 | |
| 		temporaryFirstName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
 | |
| 		if len(temporaryFirstName) == 0 {
 | |
| 			logg.ErrorCtxf(ctx, "temporaryFirstName is empty", "key", storedb.DATA_TEMPORARY_VALUE)
 | |
| 			return res, fmt.Errorf("Data error encountered")
 | |
| 		}
 | |
| 		err = store.WriteEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryFirstName))
 | |
| 		if err != nil {
 | |
| 			logg.ErrorCtxf(ctx, "failed to write firstName entry with", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName, "error", err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_firstname_set)
 | |
| 
 | |
| 		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryFirstName))
 | |
| 		if err != nil {
 | |
| 			logg.DebugCtxf(ctx, "Failed to write firtname db log entry", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName)
 | |
| 		}
 | |
| 	} else {
 | |
| 		if firstNameSet {
 | |
| 			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(firstName))
 | |
| 			if err != nil {
 | |
| 				logg.ErrorCtxf(ctx, "failed to write temporaryFirstName entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", firstName, "error", err)
 | |
| 				return res, err
 | |
| 			}
 | |
| 		} else {
 | |
| 			h.profile.InsertOrShift(0, firstName)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // SaveFamilyname updates the family name in the gdbm with the provided input.
 | |
| func (h *MenuHandlers) SaveFamilyname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var err error
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 
 | |
| 	store := h.userdataStore
 | |
| 	logdb := h.logDb
 | |
| 	familyName := string(input)
 | |
| 
 | |
| 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 | |
| 	flag_familyname_set, _ := h.flagManager.GetFlag("flag_familyname_set")
 | |
| 	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
 | |
| 	familyNameSet := h.st.MatchFlag(flag_familyname_set, true)
 | |
| 
 | |
| 	if allowUpdate {
 | |
| 		temporaryFamilyName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
 | |
| 		if len(temporaryFamilyName) == 0 {
 | |
| 			logg.ErrorCtxf(ctx, "temporaryFamilyName is empty", "key", storedb.DATA_TEMPORARY_VALUE)
 | |
| 			return res, fmt.Errorf("Data error encountered")
 | |
| 		}
 | |
| 		err = store.WriteEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
 | |
| 		if err != nil {
 | |
| 			logg.ErrorCtxf(ctx, "failed to write familyName entry with", "key", storedb.DATA_FAMILY_NAME, "value", temporaryFamilyName, "error", err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_familyname_set)
 | |
| 
 | |
| 		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
 | |
| 		if err != nil {
 | |
| 			logg.DebugCtxf(ctx, "Failed to write firtname db log entry", "key", storedb.DATA_FAMILY_NAME, "value", temporaryFamilyName)
 | |
| 		}
 | |
| 	} else {
 | |
| 		if familyNameSet {
 | |
| 			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(familyName))
 | |
| 			if err != nil {
 | |
| 				logg.ErrorCtxf(ctx, "failed to write temporaryFamilyName entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", familyName, "error", err)
 | |
| 				return res, err
 | |
| 			}
 | |
| 		} else {
 | |
| 			h.profile.InsertOrShift(1, familyName)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // VerifyYob verifies the length of the given input.
 | |
| func (h *MenuHandlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var err error
 | |
| 
 | |
| 	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
 | |
| 	date := string(input)
 | |
| 	_, err = strconv.Atoi(date)
 | |
| 	if err != nil {
 | |
| 		// If conversion fails, input is not numeric
 | |
| 		res.FlagSet = append(res.FlagSet, flag_incorrect_date_format)
 | |
| 		return res, nil
 | |
| 	}
 | |
| 
 | |
| 	if person.IsValidYOb(date) {
 | |
| 		res.FlagReset = append(res.FlagReset, flag_incorrect_date_format)
 | |
| 	} else {
 | |
| 		res.FlagSet = append(res.FlagSet, flag_incorrect_date_format)
 | |
| 	}
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // ResetIncorrectYob resets the incorrect date format flag after a new attempt.
 | |
| func (h *MenuHandlers) ResetIncorrectYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 
 | |
| 	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
 | |
| 	res.FlagReset = append(res.FlagReset, flag_incorrect_date_format)
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // SaveYOB updates the Year of Birth(YOB) in the gdbm with the provided input.
 | |
| func (h *MenuHandlers) SaveYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var err error
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 	yob := string(input)
 | |
| 	store := h.userdataStore
 | |
| 	logdb := h.logDb
 | |
| 
 | |
| 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 | |
| 	flag_yob_set, _ := h.flagManager.GetFlag("flag_yob_set")
 | |
| 
 | |
| 	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
 | |
| 	yobSet := h.st.MatchFlag(flag_yob_set, true)
 | |
| 
 | |
| 	if allowUpdate {
 | |
| 		temporaryYob, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
 | |
| 		if len(temporaryYob) == 0 {
 | |
| 			logg.ErrorCtxf(ctx, "temporaryYob is empty", "key", storedb.DATA_TEMPORARY_VALUE)
 | |
| 			return res, fmt.Errorf("Data error encountered")
 | |
| 		}
 | |
| 		err = store.WriteEntry(ctx, sessionId, storedb.DATA_YOB, []byte(temporaryYob))
 | |
| 		if err != nil {
 | |
| 			logg.ErrorCtxf(ctx, "failed to write yob entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", temporaryYob, "error", err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_yob_set)
 | |
| 
 | |
| 		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_YOB, []byte(temporaryYob))
 | |
| 		if err != nil {
 | |
| 			logg.DebugCtxf(ctx, "Failed to write yob db log entry", "key", storedb.DATA_YOB, "value", temporaryYob)
 | |
| 		}
 | |
| 	} else {
 | |
| 		if yobSet {
 | |
| 			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(yob))
 | |
| 			if err != nil {
 | |
| 				logg.ErrorCtxf(ctx, "failed to write temporaryYob entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", yob, "error", err)
 | |
| 				return res, err
 | |
| 			}
 | |
| 		} else {
 | |
| 			h.profile.InsertOrShift(3, yob)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // SaveLocation updates the location in the gdbm with the provided input.
 | |
| func (h *MenuHandlers) SaveLocation(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var err error
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 	location := string(input)
 | |
| 	store := h.userdataStore
 | |
| 	logdb := h.logDb
 | |
| 
 | |
| 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 | |
| 	flag_location_set, _ := h.flagManager.GetFlag("flag_location_set")
 | |
| 	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
 | |
| 	locationSet := h.st.MatchFlag(flag_location_set, true)
 | |
| 
 | |
| 	if allowUpdate {
 | |
| 		temporaryLocation, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
 | |
| 		if len(temporaryLocation) == 0 {
 | |
| 			logg.ErrorCtxf(ctx, "temporaryLocation is empty", "key", storedb.DATA_TEMPORARY_VALUE)
 | |
| 			return res, fmt.Errorf("Data error encountered")
 | |
| 		}
 | |
| 		err = store.WriteEntry(ctx, sessionId, storedb.DATA_LOCATION, []byte(temporaryLocation))
 | |
| 		if err != nil {
 | |
| 			logg.ErrorCtxf(ctx, "failed to write location entry with", "key", storedb.DATA_LOCATION, "value", temporaryLocation, "error", err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_location_set)
 | |
| 
 | |
| 		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_LOCATION, []byte(temporaryLocation))
 | |
| 		if err != nil {
 | |
| 			logg.DebugCtxf(ctx, "Failed to write location db log entry", "key", storedb.DATA_LOCATION, "value", temporaryLocation)
 | |
| 		}
 | |
| 	} else {
 | |
| 		if locationSet {
 | |
| 			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(location))
 | |
| 			if err != nil {
 | |
| 				logg.ErrorCtxf(ctx, "failed to write temporaryLocation entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", location, "error", err)
 | |
| 				return res, err
 | |
| 			}
 | |
| 			res.FlagSet = append(res.FlagSet, flag_location_set)
 | |
| 		} else {
 | |
| 			h.profile.InsertOrShift(4, location)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // SaveGender updates the gender in the gdbm with the provided input.
 | |
| func (h *MenuHandlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	symbol, _ := h.st.Where()
 | |
| 	var res resource.Result
 | |
| 	var err error
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 	gender := strings.Split(symbol, "_")[1]
 | |
| 	store := h.userdataStore
 | |
| 	logdb := h.logDb
 | |
| 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 | |
| 	flag_gender_set, _ := h.flagManager.GetFlag("flag_gender_set")
 | |
| 
 | |
| 	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
 | |
| 	genderSet := h.st.MatchFlag(flag_gender_set, true)
 | |
| 
 | |
| 	if allowUpdate {
 | |
| 		temporaryGender, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
 | |
| 		if len(temporaryGender) == 0 {
 | |
| 			logg.ErrorCtxf(ctx, "temporaryGender is empty", "key", storedb.DATA_TEMPORARY_VALUE)
 | |
| 			return res, fmt.Errorf("Data error encountered")
 | |
| 		}
 | |
| 		err = store.WriteEntry(ctx, sessionId, storedb.DATA_GENDER, []byte(temporaryGender))
 | |
| 		if err != nil {
 | |
| 			logg.ErrorCtxf(ctx, "failed to write gender entry with", "key", storedb.DATA_GENDER, "value", gender, "error", err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_gender_set)
 | |
| 
 | |
| 		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_GENDER, []byte(temporaryGender))
 | |
| 		if err != nil {
 | |
| 			logg.DebugCtxf(ctx, "Failed to write gender db log entry", "key", storedb.DATA_TEMPORARY_VALUE, "value", temporaryGender)
 | |
| 		}
 | |
| 
 | |
| 	} else {
 | |
| 		if genderSet {
 | |
| 			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(gender))
 | |
| 			if err != nil {
 | |
| 				logg.ErrorCtxf(ctx, "failed to write temporaryGender entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", gender, "error", err)
 | |
| 				return res, err
 | |
| 			}
 | |
| 		} else {
 | |
| 			h.profile.InsertOrShift(2, gender)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // SaveOfferings updates the offerings(goods and services provided by the user) in the gdbm with the provided input.
 | |
| func (h *MenuHandlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var err error
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 
 | |
| 	offerings := string(input)
 | |
| 	store := h.userdataStore
 | |
| 	logdb := h.logDb
 | |
| 
 | |
| 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 | |
| 	flag_offerings_set, _ := h.flagManager.GetFlag("flag_offerings_set")
 | |
| 
 | |
| 	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
 | |
| 	offeringsSet := h.st.MatchFlag(flag_offerings_set, true)
 | |
| 
 | |
| 	if allowUpdate {
 | |
| 		temporaryOfferings, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
 | |
| 		if len(temporaryOfferings) == 0 {
 | |
| 			logg.ErrorCtxf(ctx, "temporaryOfferings is empty", "key", storedb.DATA_TEMPORARY_VALUE)
 | |
| 			return res, fmt.Errorf("Data error encountered")
 | |
| 		}
 | |
| 		err = store.WriteEntry(ctx, sessionId, storedb.DATA_OFFERINGS, []byte(temporaryOfferings))
 | |
| 		if err != nil {
 | |
| 			logg.ErrorCtxf(ctx, "failed to write offerings entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", offerings, "error", err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_offerings_set)
 | |
| 
 | |
| 		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryOfferings))
 | |
| 		if err != nil {
 | |
| 			logg.DebugCtxf(ctx, "Failed to write offerings db log entry", "key", storedb.DATA_OFFERINGS, "value", offerings)
 | |
| 		}
 | |
| 	} else {
 | |
| 		if offeringsSet {
 | |
| 			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(offerings))
 | |
| 			if err != nil {
 | |
| 				logg.ErrorCtxf(ctx, "failed to write temporaryOfferings entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", offerings, "error", err)
 | |
| 				return res, err
 | |
| 			}
 | |
| 		} else {
 | |
| 			h.profile.InsertOrShift(5, offerings)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // GetCurrentProfileInfo retrieves specific profile fields based on the current state of the USSD session.
 | |
| // Uses flag management system to track profile field status and handle menu navigation.
 | |
| func (h *MenuHandlers) GetCurrentProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var profileInfo []byte
 | |
| 	var defaultValue string
 | |
| 	var err error
 | |
| 
 | |
| 	flag_firstname_set, _ := h.flagManager.GetFlag("flag_firstname_set")
 | |
| 	flag_familyname_set, _ := h.flagManager.GetFlag("flag_familyname_set")
 | |
| 	flag_yob_set, _ := h.flagManager.GetFlag("flag_yob_set")
 | |
| 	flag_gender_set, _ := h.flagManager.GetFlag("flag_gender_set")
 | |
| 	flag_location_set, _ := h.flagManager.GetFlag("flag_location_set")
 | |
| 	flag_offerings_set, _ := h.flagManager.GetFlag("flag_offerings_set")
 | |
| 	flag_back_set, _ := h.flagManager.GetFlag("flag_back_set")
 | |
| 
 | |
| 	res.FlagReset = append(res.FlagReset, flag_back_set)
 | |
| 
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 	language, ok := ctx.Value("Language").(lang.Language)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("value for 'Language' is not of type lang.Language")
 | |
| 	}
 | |
| 	code := language.Code
 | |
| 	if code == "swa" {
 | |
| 		defaultValue = "Haipo"
 | |
| 	} else {
 | |
| 		defaultValue = "Not Provided"
 | |
| 	}
 | |
| 
 | |
| 	sm, _ := h.st.Where()
 | |
| 	parts := strings.SplitN(sm, "_", 2)
 | |
| 	filename := parts[1]
 | |
| 	dbKeyStr := "DATA_" + strings.ToUpper(filename)
 | |
| 	logg.InfoCtxf(ctx, "GetCurrentProfileInfo", "filename", filename, "dbKeyStr:", dbKeyStr)
 | |
| 	dbKey, err := storedb.StringToDataTyp(dbKeyStr)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		return res, err
 | |
| 	}
 | |
| 	store := h.userdataStore
 | |
| 
 | |
| 	switch dbKey {
 | |
| 	case storedb.DATA_FIRST_NAME:
 | |
| 		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_FIRST_NAME)
 | |
| 		if err != nil {
 | |
| 			if db.IsNotFound(err) {
 | |
| 				res.Content = defaultValue
 | |
| 				break
 | |
| 			}
 | |
| 			logg.ErrorCtxf(ctx, "Failed to read first name entry with", "key", "error", storedb.DATA_FIRST_NAME, err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_firstname_set)
 | |
| 		res.Content = string(profileInfo)
 | |
| 	case storedb.DATA_FAMILY_NAME:
 | |
| 		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME)
 | |
| 		if err != nil {
 | |
| 			if db.IsNotFound(err) {
 | |
| 				res.Content = defaultValue
 | |
| 				break
 | |
| 			}
 | |
| 			logg.ErrorCtxf(ctx, "Failed to read family name entry with", "key", "error", storedb.DATA_FAMILY_NAME, err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_familyname_set)
 | |
| 		res.Content = string(profileInfo)
 | |
| 
 | |
| 	case storedb.DATA_GENDER:
 | |
| 		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_GENDER)
 | |
| 		if err != nil {
 | |
| 			if db.IsNotFound(err) {
 | |
| 				res.Content = defaultValue
 | |
| 				break
 | |
| 			}
 | |
| 			logg.ErrorCtxf(ctx, "Failed to read gender entry with", "key", "error", storedb.DATA_GENDER, err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_gender_set)
 | |
| 		res.Content = string(profileInfo)
 | |
| 	case storedb.DATA_YOB:
 | |
| 		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_YOB)
 | |
| 		if err != nil {
 | |
| 			if db.IsNotFound(err) {
 | |
| 				res.Content = defaultValue
 | |
| 				break
 | |
| 			}
 | |
| 			logg.ErrorCtxf(ctx, "Failed to read year of birth(yob) entry with", "key", "error", storedb.DATA_YOB, err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_yob_set)
 | |
| 		res.Content = string(profileInfo)
 | |
| 	case storedb.DATA_LOCATION:
 | |
| 		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_LOCATION)
 | |
| 		if err != nil {
 | |
| 			if db.IsNotFound(err) {
 | |
| 				res.Content = defaultValue
 | |
| 				break
 | |
| 			}
 | |
| 			logg.ErrorCtxf(ctx, "Failed to read location entry with", "key", "error", storedb.DATA_LOCATION, err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_location_set)
 | |
| 		res.Content = string(profileInfo)
 | |
| 	case storedb.DATA_OFFERINGS:
 | |
| 		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS)
 | |
| 		if err != nil {
 | |
| 			if db.IsNotFound(err) {
 | |
| 				res.Content = defaultValue
 | |
| 				break
 | |
| 			}
 | |
| 			logg.ErrorCtxf(ctx, "Failed to read offerings entry with", "key", "error", storedb.DATA_OFFERINGS, err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		res.FlagSet = append(res.FlagSet, flag_offerings_set)
 | |
| 		res.Content = string(profileInfo)
 | |
| 	case storedb.DATA_ACCOUNT_ALIAS:
 | |
| 		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS)
 | |
| 		if err != nil {
 | |
| 			if db.IsNotFound(err) {
 | |
| 				res.Content = defaultValue
 | |
| 				break
 | |
| 			}
 | |
| 			logg.ErrorCtxf(ctx, "Failed to read account alias entry with", "key", "error", storedb.DATA_ACCOUNT_ALIAS, err)
 | |
| 			return res, err
 | |
| 		}
 | |
| 		alias := string(profileInfo)
 | |
| 		if alias == "" {
 | |
| 			res.Content = defaultValue
 | |
| 		} else {
 | |
| 			res.Content = alias
 | |
| 		}
 | |
| 	default:
 | |
| 		break
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // GetProfileInfo provides a comprehensive view of a user's profile.
 | |
| func (h *MenuHandlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	var defaultValue string
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 	language, ok := ctx.Value("Language").(lang.Language)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("value for 'Language' is not of type lang.Language")
 | |
| 	}
 | |
| 	code := language.Code
 | |
| 	if code == "swa" {
 | |
| 		defaultValue = "Haipo"
 | |
| 	} else {
 | |
| 		defaultValue = "Not Provided"
 | |
| 	}
 | |
| 
 | |
| 	// Helper function to handle nil byte slices and convert them to string
 | |
| 	getEntryOrDefault := func(entry []byte, err error) string {
 | |
| 		if err != nil || entry == nil {
 | |
| 			return defaultValue
 | |
| 		}
 | |
| 		return string(entry)
 | |
| 	}
 | |
| 	store := h.userdataStore
 | |
| 	// Retrieve user data as strings with fallback to defaultValue
 | |
| 	firstName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_FIRST_NAME))
 | |
| 	familyName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME))
 | |
| 	yob := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_YOB))
 | |
| 	gender := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_GENDER))
 | |
| 	location := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_LOCATION))
 | |
| 	offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS))
 | |
| 	alias := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS))
 | |
| 
 | |
| 	if alias != defaultValue && alias != "" {
 | |
| 		alias = strings.Split(alias, ".")[0]
 | |
| 	} else {
 | |
| 		alias = defaultValue
 | |
| 	}
 | |
| 
 | |
| 	// Construct the full name
 | |
| 	name := person.ConstructName(firstName, familyName, defaultValue)
 | |
| 
 | |
| 	// Calculate age from year of birth
 | |
| 	age := defaultValue
 | |
| 	if yob != defaultValue {
 | |
| 		if yobInt, err := strconv.Atoi(yob); err == nil {
 | |
| 			age = strconv.Itoa(person.CalculateAgeWithYOB(yobInt))
 | |
| 		} else {
 | |
| 			return res, fmt.Errorf("invalid year of birth: %v", err)
 | |
| 		}
 | |
| 	}
 | |
| 	switch language.Code {
 | |
| 	case "eng":
 | |
| 		res.Content = fmt.Sprintf(
 | |
| 			"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\nYour alias: %s\n",
 | |
| 			name, gender, age, location, offerings, alias,
 | |
| 		)
 | |
| 	case "swa":
 | |
| 		res.Content = fmt.Sprintf(
 | |
| 			"Jina: %s\nJinsia: %s\nUmri: %s\nEneo: %s\nUnauza: %s\nLakabu yako: %s\n",
 | |
| 			name, gender, age, location, offerings, alias,
 | |
| 		)
 | |
| 	default:
 | |
| 		res.Content = fmt.Sprintf(
 | |
| 			"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\nYour alias: %s\n",
 | |
| 			name, gender, age, location, offerings, alias,
 | |
| 		)
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| // handles bulk updates of profile information.
 | |
| func (h *MenuHandlers) insertProfileItems(ctx context.Context, sessionId string, res *resource.Result) error {
 | |
| 	var err error
 | |
| 	userStore := h.userdataStore
 | |
| 	profileFlagNames := []string{
 | |
| 		"flag_firstname_set",
 | |
| 		"flag_familyname_set",
 | |
| 		"flag_yob_set",
 | |
| 		"flag_gender_set",
 | |
| 		"flag_location_set",
 | |
| 		"flag_offerings_set",
 | |
| 	}
 | |
| 	profileDataKeys := []storedb.DataTyp{
 | |
| 		storedb.DATA_FIRST_NAME,
 | |
| 		storedb.DATA_FAMILY_NAME,
 | |
| 		storedb.DATA_GENDER,
 | |
| 		storedb.DATA_YOB,
 | |
| 		storedb.DATA_LOCATION,
 | |
| 		storedb.DATA_OFFERINGS,
 | |
| 	}
 | |
| 	for index, profileItem := range h.profile.ProfileItems {
 | |
| 		// Ensure the profileItem is not "0"(is set)
 | |
| 		if profileItem != "0" {
 | |
| 			flag, _ := h.flagManager.GetFlag(profileFlagNames[index])
 | |
| 			isProfileItemSet := h.st.MatchFlag(flag, true)
 | |
| 			if !isProfileItemSet {
 | |
| 				err = userStore.WriteEntry(ctx, sessionId, profileDataKeys[index], []byte(profileItem))
 | |
| 				if err != nil {
 | |
| 					logg.ErrorCtxf(ctx, "failed to write profile entry with", "key", profileDataKeys[index], "value", profileItem, "error", err)
 | |
| 					return err
 | |
| 				}
 | |
| 				res.FlagSet = append(res.FlagSet, flag)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // UpdateAllProfileItems  is used to persist all the  new profile information and setup  the required profile flags.
 | |
| func (h *MenuHandlers) UpdateAllProfileItems(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | |
| 	var res resource.Result
 | |
| 	sessionId, ok := ctx.Value("SessionId").(string)
 | |
| 	if !ok {
 | |
| 		return res, fmt.Errorf("missing session")
 | |
| 	}
 | |
| 	err := h.insertProfileItems(ctx, sessionId, &res)
 | |
| 	if err != nil {
 | |
| 		return res, err
 | |
| 	}
 | |
| 	return res, nil
 | |
| }
 |