From fea0befd9fa310f16cf7be7aaa277c1f3c75441d Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Tue, 1 Jul 2025 02:04:45 +0300 Subject: [PATCH] added profile.go for profile related functionality --- handlers/application/menuhandler.go | 603 --------------------------- handlers/application/profile.go | 616 ++++++++++++++++++++++++++++ 2 files changed, 616 insertions(+), 603 deletions(-) create mode 100644 handlers/application/profile.go diff --git a/handlers/application/menuhandler.go b/handlers/application/menuhandler.go index 77885e0..b184126 100644 --- a/handlers/application/menuhandler.go +++ b/handlers/application/menuhandler.go @@ -21,7 +21,6 @@ import ( "git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/state" commonlang "git.grassecon.net/grassrootseconomics/common/lang" - "git.grassecon.net/grassrootseconomics/common/person" "git.grassecon.net/grassrootseconomics/common/pin" "git.grassecon.net/grassrootseconomics/sarafu-api/remote" "git.grassecon.net/grassrootseconomics/sarafu-vise/config" @@ -278,339 +277,6 @@ func (h *MenuHandlers) ResetUnregisteredNumber(ctx context.Context, sym string, return res, nil } -// 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 -} - // ResetAllowUpdate resets the allowupdate flag that allows a user to update profile data. func (h *MenuHandlers) ResetAllowUpdate(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result @@ -619,275 +285,6 @@ func (h *MenuHandlers) ResetAllowUpdate(ctx context.Context, sym string, input [ 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 -} - // ResetAccountAuthorized resets the account authorization flag after a successful PIN entry. func (h *MenuHandlers) ResetAccountAuthorized(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result diff --git a/handlers/application/profile.go b/handlers/application/profile.go new file mode 100644 index 0000000..62b264d --- /dev/null +++ b/handlers/application/profile.go @@ -0,0 +1,616 @@ +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 +}