Skip to content

Commit

Permalink
copy route adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
capture120 committed Apr 18, 2024
1 parent 2640852 commit 057779e
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 17 deletions.
23 changes: 17 additions & 6 deletions backend/src/controllers/portfolio.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import (
"backend/src/services"
"net/http"

// "fmt"

"github.com/gin-gonic/gin"

"backend/src/models"
)

type PortfolioController struct {
Expand All @@ -21,20 +25,26 @@ func NewPortfolioController(portfolioService *services.PortfolioService, etradeS

// CopyPortfolio copies the target user's portfolio to the current user's portfolio
func (etc *PortfolioController) CopyPortfolio(c *gin.Context) {
targetUserID := c.Param("target_user_id")
currentUserID := c.Param("current_user_id")
currentUserID := c.Query("current_user_id")
targetUserID := c.Query("target_user_id")

// get current user's portfolio. If it doesn't exist, return error
// get current user's portfolio. If it doesn't exist, create empty portfolio
currentUserPortfolio, err := etc.portfolioService.GetUserPortfolio(currentUserID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": "Current User does not have an existing portfolio"})
return
// create empty portfolio for the user
emptyPortfolio := &models.UserPortfolio{}
newPortfolio, createErr := etc.portfolioService.CreateUserPortfolio(currentUserID, emptyPortfolio)
currentUserPortfolio = newPortfolio
if createErr != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create empty portfolio", "errorMessage": createErr.Error()})
return
}
}

// get target user's portfolio. If it doesn't exist, return error
targetPortfolio, err := etc.portfolioService.GetUserPortfolio(targetUserID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": "Target User does not have portfolio to copy"})
c.JSON(http.StatusBadRequest, gin.H{"message": "Target User does not have portfolio to copy", "errorMessage": err.Error()})
return
}

Expand All @@ -59,6 +69,7 @@ func (etc *PortfolioController) CopyPortfolio(c *gin.Context) {
}

c.JSON(http.StatusOK, updatedPortfolio)
// c.JSON(http.StatusOK, copiedPortfolio)
}

// GetUserPortfolio returns the user's portfolio
Expand Down
2 changes: 1 addition & 1 deletion backend/src/routes/portfolio.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func SetupPortfolioRoutes(router *gin.Engine, db *gorm.DB) {

portfolioRoutes := router.Group("/portfolio")
{
portfolioRoutes.PUT("/:target_user_id/:current_user_id", portfolioController.CopyPortfolio)
portfolioRoutes.PUT("", portfolioController.CopyPortfolio)
/* different than getportfolio in etrade, returns single object for simplicity
keep etrade getportfolio route to match actual Etrade data
use either call depending on what you need
Expand Down
28 changes: 28 additions & 0 deletions backend/src/services/portfolio.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ func (os *PortfolioService) CopyPortfolio(currentUserPortfolio models.UserPortfo
var newPositions []models.Position
targetPositions := targetPortfolio.Positions
for _, position := range targetPositions {
// check if position exists in currentUserPortfolio.positions (matching by position.Ticker)
positionExists := false
var matchingPosition models.Position
for i, p := range currentUserPortfolio.Positions {
if p.Ticker == position.Ticker {
positionExists = true
matchingPosition = currentUserPortfolio.Positions[i]
break
}
}

// if position exists, update the quantity -> skip to next position
if positionExists {
matchingPosition.Quantity += position.Quantity
continue
}

// if position doesn't already exist, copy the position
newPosition := models.Position{
UserPortfolioID: currentUserPortfolio.ID,
PositionID: position.PositionID,
Expand Down Expand Up @@ -66,3 +84,13 @@ func (os *PortfolioService) GetUserPortfolio(userID string) (*models.UserPortfol
}
return &portfolio, nil
}

// CreateUserPortfolio creates a new portfolio for the user.
func (os *PortfolioService) CreateUserPortfolio(userID string, portfolio *models.UserPortfolio) (*models.UserPortfolio, error) {
portfolio.UserID = userID
err := os.DB.Create(portfolio).Error
if err != nil {
return nil, err
}
return portfolio, nil
}
28 changes: 20 additions & 8 deletions frontend/pages/Copy/CopyTradesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import {
AuthNavigationProp,
} from '../../types/navigationTypes';
import { CopyRouteParams } from '../../types/types';
// import { User } from '../../types/types';
// import { copyTrades } from '../../services/copy';
import { copyTrades } from '../../services/copy';

function CopyTradesPage() {
const { session } = useSession();
Expand All @@ -38,7 +37,8 @@ function CopyTradesPage() {
}

try {
// await copyTrades(session?.user.id as string, user.username);
await copyTrades(session?.user.id as string, user?.id);
// Alert.alert(`session?.user.id: ${session?.user.id} | user.id: ${user?.id}`);
} catch (error) {
Alert.alert('Error', 'Failed to copy trades');
return;
Expand Down Expand Up @@ -69,10 +69,16 @@ function CopyTradesPage() {
<View style={styles.inputGroup}>
<Text style={styles.boldLabel}>Investment Amount</Text>
<TextInput
style={styles.input}
value={`$${investmentAmount}`}
onChangeText={setInvestmentAmount}
keyboardType="numeric"
value={`$${investmentAmount}`}
onChangeText={text => {
if (text.startsWith('$')) {
text = text.slice(1);
}
text = text.replace(/[^0-9]/g, '');
setInvestmentAmount(text);
}}
style={styles.input}
/>
<Text style={styles.smallText}>
This investment will proportionally copy this investor’s portfolio.
Expand All @@ -92,10 +98,16 @@ function CopyTradesPage() {
<View style={styles.stopLossContainer}>
<Text style={styles.label}>Investment Falls Below</Text>
<TextInput
keyboardType="numeric"
value={`$${stopLossAmount}`}
onChangeText={setStopLossAmount}
onChangeText={text => {
if (text.startsWith('$')) {
text = text.slice(1);
}
text = text.replace(/[^0-9]/g, '');
setStopLossAmount(text);
}}
style={styles.input}
keyboardType="numeric"
/>
</View>
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/reducers/onboarding/onboardingReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const onboardingSlice = createSlice({
financialGoalsShortTerm: [],
financialGoalsLongTerm: [],
financialLiteracy: [],
isOnboarding: 'normal', // 'onboarding', 'normal', 'makingPost'
isOnboarding: 'onboarding', // 'onboarding', 'normal', 'makingPost'
},
reducers: {
updateFirstName(state, action) {
Expand Down
2 changes: 1 addition & 1 deletion frontend/services/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Redirect } from '../types/types';

export const copyTrades = async (currentUserId: string, targetUserId: string) => {
const response: AxiosResponse<Redirect> = await axios.post<Redirect>(
`http://${API_LINK}/portfolio/${currentUserId}/${targetUserId}`
`http://${API_LINK}/portfolio?current_user_id=${currentUserId}&target_user_id=${targetUserId}`
);
return response.data;
};

0 comments on commit 057779e

Please sign in to comment.