diff --git a/internal/expense/database.go b/internal/expense/database.go
index 98e8398..7493b45 100644
--- a/internal/expense/database.go
+++ b/internal/expense/database.go
@@ -32,6 +32,31 @@ func (db *Database) CreateExpense(expense *Expense) error {
return err
}
+func (db Database) GetExpensesOfAnAccountBetween(id, from, to string) ([]*Expense, error) {
+ q := `
+ SELECT a.id, a.account_id, a.value, a.type_expense, a.expense_date, a.created_at, a.updated_at, a.libelle
+ FROM public.expense a
+ WHERE a.account_id = $1
+ AND a.expense_date BETWEEN $2 and $3
+ `
+ rows, err := db.Session.Query(q, id, from, to)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ es := make([]*Expense, 0)
+ for rows.Next() {
+ e := Expense{}
+ err := rows.Scan(&e.ID, &e.AccountId, &e.Value, &e.TypeExpense, &e.ExpenseDate, &e.CreatedAt, &e.UpdatedAt, &e.Libelle)
+ if err != nil {
+ return nil, err
+ }
+ es = append(es, &e)
+ }
+ return es, nil
+}
+
func (db Database) GetAllExpensesOfAnAccount(id string) ([]*Expense, error) {
q := `
SELECT a.id, a.account_id, a.value, a.type_expense, a.expense_date, a.created_at, a.updated_at, a.libelle
diff --git a/internal/expense/handler.go b/internal/expense/handler.go
index 073456f..281a9a9 100644
--- a/internal/expense/handler.go
+++ b/internal/expense/handler.go
@@ -9,6 +9,7 @@ import (
"nos-comptes/internal/storage/model"
"nos-comptes/internal/storage/validators"
"nos-comptes/internal/utils"
+ "time"
"github.com/gin-gonic/gin"
)
@@ -78,7 +79,31 @@ func (c *Context) DeleteExpense(gc *gin.Context) {
func (c *Context) GetAllExpenses(gc *gin.Context) {
accountId := gc.Param("accountId")
- expenses, err := c.service.GetAllExpensesOfAnAccount(accountId)
+ from := gc.Query("from")
+ to := gc.Query("to")
+ var expenses []*Expense
+ var err error
+ if from != "" || to != "" {
+ if to == "" {
+ fromParsed, err := time.Parse("2006-01-02", from)
+ if err == nil {
+ to = time.Now().Format("2006-01-02")
+ } else {
+ to = fromParsed.AddDate(0, 1, 0).Format("2006-01-02")
+ }
+ }
+ if from == "" {
+ toParsed, err := time.Parse("2006-01-02", to)
+ if err == nil {
+ from = "1900-01-01"
+ } else {
+ from = toParsed.AddDate(0, -1, 0).Format("2006-01-02")
+ }
+ }
+ expenses, err = c.service.GetExpensesOfAnAccountBetween(accountId, from, to)
+ } else {
+ expenses, err = c.service.GetAllExpensesOfAnAccount(accountId)
+ }
if e, ok := err.(*model.APIError); ok {
utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetAllExpenses: get expenses")
utils.JSONErrorWithMessage(gc.Writer, *e, e.Description)
diff --git a/internal/expense/service.go b/internal/expense/service.go
index d2d8556..c7162b2 100644
--- a/internal/expense/service.go
+++ b/internal/expense/service.go
@@ -14,6 +14,26 @@ type Service struct {
db *Database
}
+func (s Service) GetExpensesOfAnAccountBetween(accountId, from, to string) ([]*Expense, error) {
+ expenses, err := s.db.GetExpensesOfAnAccountBetween(accountId, from, to)
+ utils.GetLogger().Info(err)
+ if e, ok := err.(*dao.Error); ok {
+ switch {
+ case e.Type == dao.ErrTypeNotFound:
+ return nil, &model.ErrNotFound
+ default:
+ return nil, &model.ErrInternalServer
+ }
+ } else if err != nil {
+ return nil, &model.ErrInternalServer
+ }
+
+ if expenses == nil {
+ return nil, &model.ErrNotFound
+ }
+ return expenses, nil
+}
+
func (s Service) GetAllExpensesOfAnAccount(accountId string) ([]*Expense, error) {
expenses, err := s.db.GetAllExpensesOfAnAccount(accountId)
utils.GetLogger().Info(err)
diff --git a/internal/jointaccount/database.go b/internal/jointaccount/database.go
new file mode 100644
index 0000000..40edc74
--- /dev/null
+++ b/internal/jointaccount/database.go
@@ -0,0 +1,116 @@
+package jointaccount
+
+import (
+ "fmt"
+ "nos-comptes/internal/storage/dao"
+ "nos-comptes/internal/storage/dao/postgresql"
+ "nos-comptes/internal/utils"
+
+ "github.com/lib/pq"
+)
+
+type Database struct {
+ *postgresql.DatabasePostgreSQL
+}
+
+func (db *Database) GetAllJointaccountOfUser(id string) ([]*Jointaccount, error) {
+ q := `
+ SELECT a.id, a.user_id, a.name, a.provider, a.created_at, a.updated_at
+ FROM public.jointaccount a
+ WHERE a.user_id = $1
+ `
+ rows, err := db.Session.Query(q, id)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ as := make([]*Jointaccount, 0)
+ for rows.Next() {
+ a := Jointaccount{}
+ err := rows.Scan(&a.ID, &a.UserId, &a.Name, &a.Provider, &a.CreatedAt, &a.UpdatedAt)
+ if err != nil {
+ return nil, err
+ }
+ as = append(as, &a)
+ }
+ return as, nil
+}
+
+func (db *Database) GetJointaccountWithNameForUser(name string, id string) (*Jointaccount, error) {
+ q := `
+ SELECT a.id, a.user_id, a.name, a.provider, a.created_at, a.updated_at
+ FROM public.jointaccount a
+ WHERE a.user_id = $1
+ AND a.name = $2
+ `
+ row, err := db.Session.Query(q, id, name)
+ if !row.Next() {
+ return nil, dao.NewDAOError(dao.ErrTypeNotFound, fmt.Errorf("No row found"))
+ }
+ a := Jointaccount{}
+ row.Scan(&a.ID, &a.UserId, &a.Name, &a.Provider, &a.CreatedAt, &a.UpdatedAt)
+ if row.Next() {
+ return nil, fmt.Errorf("Impossibru")
+ }
+ if errPq, ok := err.(*pq.Error); ok {
+ return nil, postgresql.HandlePgError(errPq)
+ }
+ if err != nil {
+ utils.GetLogger().Info(err)
+ return nil, err
+ }
+ return &a, nil
+}
+
+func (db *Database) CreateJointaccount(jointaccount *Jointaccount) error {
+ q := `
+ INSERT INTO public.jointaccount
+ (Name, Provider, user_id)
+ VALUES
+ ($1, $2, $3)
+ RETURNING id, created_at
+ `
+
+ err := db.Session.
+ QueryRow(q, jointaccount.Name, jointaccount.Provider, jointaccount.UserId).
+ Scan(&jointaccount.ID, &jointaccount.CreatedAt)
+ if errPq, ok := err.(*pq.Error); ok {
+ return postgresql.HandlePgError(errPq)
+ }
+ return err
+
+}
+
+func (db *Database) DeleteJointaccountOfAnUser(userId, jointaccountId string) error {
+ query := `
+ DELETE FROM jointaccount
+ WHERE user_id = $1
+ AND id = $2;`
+ _, err := db.Session.Exec(query, userId, jointaccountId)
+ return err
+}
+
+func (db *Database) GetASpecificJointaccountForUser(userId, jointaccountId string) (*Jointaccount, error) {
+ q := `
+ SELECT a.id, a.user_id, a.name, a.provider, a.created_at, a.updated_at
+ FROM public.jointaccount a
+ WHERE a.user_id = $1
+ AND a.id = $2
+ `
+ row := db.Session.QueryRow(q, userId, jointaccountId)
+ a := Jointaccount{}
+ err := row.Scan(&a.ID, &a.UserId, &a.Name, &a.Provider, &a.CreatedAt, &a.UpdatedAt)
+ if errPq, ok := err.(*pq.Error); ok {
+ return nil, postgresql.HandlePgError(errPq)
+ }
+ if err != nil {
+ utils.GetLogger().Info(err)
+ return nil, err
+ }
+ return &a, nil
+}
+
+func NewDatabase(db *postgresql.DatabasePostgreSQL) *Database {
+ return &Database{db}
+}
diff --git a/internal/jointaccount/handler.go b/internal/jointaccount/handler.go
new file mode 100644
index 0000000..779ab50
--- /dev/null
+++ b/internal/jointaccount/handler.go
@@ -0,0 +1,100 @@
+package jointaccount
+
+import (
+ "net/http"
+ "nos-comptes/handler"
+ "nos-comptes/internal/storage/dao/postgresql"
+ "nos-comptes/internal/storage/model"
+ "nos-comptes/internal/storage/validators"
+ "nos-comptes/internal/user"
+ "nos-comptes/internal/utils"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Context struct {
+ service *Service
+ db *Database
+ userService *user.Service
+ *handler.Context
+}
+
+func (c *Context) GetAllJointaccountOfUser(gc *gin.Context) {
+ userId := gc.Param("userId")
+ jointaccounts, err := c.service.GetAllJointaccountOfUser(userId)
+ if e, ok := err.(*model.APIError); ok {
+ utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetAllJointaccounts: get jointaccounts")
+ utils.JSONErrorWithMessage(gc.Writer, *e, e.Description)
+ } else if err != nil {
+ utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get jointaccounts")
+ utils.JSONError(gc.Writer, model.ErrInternalServer)
+ return
+ }
+
+ if len(jointaccounts) == 0 {
+ utils.JSON(gc.Writer, http.StatusNoContent, nil)
+ } else {
+ utils.JSON(gc.Writer, http.StatusOK, jointaccounts)
+ }
+
+}
+
+func (c *Context) CreateJointaccountOfUser(gc *gin.Context) {
+ userId := gc.Param("userId")
+
+ var jointaccount Jointaccount
+ var jointaccountEditable JointaccountEditable
+ if err := gc.BindJSON(&jointaccountEditable); err != nil {
+ utils.JSONError(gc.Writer, validators.NewDataValidationAPIError(err))
+ return
+ }
+ jointaccount = Jointaccount{JointaccountEditable: jointaccountEditable, UserId: userId}
+ jointaccountFound, err := c.service.GetJointaccountWithNameForUser(jointaccount.Name, userId)
+ if e, ok := err.(*model.APIError); ok {
+ if e.Type != model.ErrNotFound.Type {
+ utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetJointaccount: get jointaccount error")
+ utils.JSONErrorWithMessage(gc.Writer, *e, e.Description)
+ return
+ }
+ } else if err != nil {
+ utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get jointaccount")
+ utils.JSONError(gc.Writer, model.ErrInternalServer)
+ return
+ }
+
+ if jointaccountFound != nil {
+ utils.GetLoggerFromCtx(gc).WithError(&model.ErrAlreadyExists).WithField("type", model.ErrAlreadyExists.Type).Error("error CreateJointaccount: jointaccount already exists")
+ utils.JSONErrorWithMessage(gc.Writer, model.ErrAlreadyExists, "jointaccount already exists with the same Name")
+ return
+ }
+ jointaccount.UserId = userId
+ jointaccountSaved, err := c.service.CreateJointaccount(jointaccount)
+ if err != nil {
+ utils.GetLogger().Info(err)
+ utils.JSONErrorWithMessage(gc.Writer, model.ErrInternalServer, err.Error())
+ return
+ }
+ utils.JSON(gc.Writer, http.StatusCreated, jointaccountSaved)
+ return
+}
+
+func (c *Context) DeleteJointaccountOfUser(gc *gin.Context) {
+ userId := gc.Param("userId")
+ jointaccountId := gc.Param("jointaccountId")
+ c.service.DeleteJointaccountOfUser(userId, jointaccountId)
+
+}
+
+func (c *Context) GetSpecificJointaccountOfUser(gc *gin.Context) {
+ userId := gc.Param("userId")
+ jointaccountId := gc.Param("jointaccountId")
+ jointaccount, _ := c.service.GetASpecificJointaccountForUser(userId, jointaccountId)
+ utils.JSON(gc.Writer, http.StatusOK, jointaccount)
+}
+
+func NewHandler(ctx *handler.Context, db *postgresql.DatabasePostgreSQL) *Context {
+ database := NewDatabase(db)
+ service := NewService(database)
+ userService := user.NewService(user.NewDatabase(db))
+ return &Context{service: service, db: database, userService: userService, Context: ctx}
+}
diff --git a/internal/jointaccount/model.go b/internal/jointaccount/model.go
new file mode 100644
index 0000000..abb2635
--- /dev/null
+++ b/internal/jointaccount/model.go
@@ -0,0 +1,16 @@
+package jointaccount
+
+import "time"
+
+type Jointaccount struct {
+ JointaccountEditable
+ UserId string `json:"userId,omitempty"`
+}
+
+type JointaccountEditable struct {
+ ID string `json:"id,omitempty"`
+ Name string `json:"name"`
+ Provider string `json:"provider"`
+ CreatedAt time.Time `json:"createdAt,omitempty"`
+ UpdatedAt *time.Time `json:"updatedAt,omitempty"`
+}
diff --git a/internal/jointaccount/service.go b/internal/jointaccount/service.go
new file mode 100644
index 0000000..5f95c41
--- /dev/null
+++ b/internal/jointaccount/service.go
@@ -0,0 +1,62 @@
+package jointaccount
+
+import (
+ "nos-comptes/internal/storage/dao"
+ "nos-comptes/internal/storage/model"
+)
+
+type Service struct {
+ db *Database
+}
+
+func (s *Service) GetAllJointaccountOfUser(userId string) ([]*Jointaccount, error) {
+ jointaccounts, err := s.db.GetAllJointaccountOfUser(userId)
+ if e, ok := err.(*dao.Error); ok {
+ switch {
+ case e.Type == dao.ErrTypeNotFound:
+ return nil, &model.ErrNotFound
+ default:
+ return nil, &model.ErrInternalServer
+ }
+ } else if err != nil {
+ return nil, &model.ErrInternalServer
+ }
+
+ if jointaccounts == nil {
+ return nil, &model.ErrNotFound
+ }
+ return jointaccounts, nil
+}
+
+func (s *Service) GetJointaccountWithNameForUser(name string, id string) (*Jointaccount, error) {
+ jointaccount, err := s.db.GetJointaccountWithNameForUser(name, id)
+ if e, ok := err.(*dao.Error); ok {
+ switch {
+ case e.Type == dao.ErrTypeNotFound:
+ return nil, &model.ErrNotFound
+ default:
+ return nil, &model.ErrInternalServer
+ }
+ } else if err != nil {
+ return nil, &model.ErrInternalServer
+ }
+ return jointaccount, nil
+}
+
+func (s *Service) CreateJointaccount(jointaccount Jointaccount) (*Jointaccount, error) {
+ err := s.db.CreateJointaccount(&jointaccount)
+ return &jointaccount, err
+}
+
+func (s *Service) DeleteJointaccountOfUser(userId, jointaccountId string) error {
+ return s.db.DeleteJointaccountOfAnUser(userId, jointaccountId)
+}
+
+func (s *Service) GetASpecificJointaccountForUser(userId, jointaccountId string) (*Jointaccount, error) {
+ return s.db.GetASpecificJointaccountForUser(userId, jointaccountId)
+
+}
+
+func NewService(database *Database) *Service {
+ return &Service{db: database}
+}
diff --git a/internal/jointexpense/database.go b/internal/jointexpense/database.go
new file mode 100644
index 0000000..ba6b9f5
--- /dev/null
+++ b/internal/jointexpense/database.go
@@ -0,0 +1,86 @@
+package jointexpense
+
+import (
+ "nos-comptes/internal/storage/dao/postgresql"
+ "nos-comptes/internal/utils"
+
+ "github.com/lib/pq"
+)
+
+type Database struct {
+ *postgresql.DatabasePostgreSQL
+}
+
+func (db *Database) CreateJointexpense(jointexpense *Jointexpense) error {
+ q := `
+ INSERT INTO public.jointexpense
+ (jointaccount_id, value, type_jointexpense, jointexpense_date, libelle)
+ VALUES
+ ($1, $2, $3, $4, $5)
+ RETURNING id, created_at
+ `
+
+ err := db.Session.
+ QueryRow(q, jointexpense.JointaccountId, jointexpense.Value, jointexpense.TypeJointexpense, jointexpense.JointexpenseDate, jointexpense.Libelle).
+ Scan(&jointexpense.ID, &jointexpense.CreatedAt)
+ if err != nil {
+ utils.GetLogger().Info(err)
+ }
+ if errPq, ok := err.(*pq.Error); ok {
+ return postgresql.HandlePgError(errPq)
+ }
+ return err
+}
+
+func (db Database) GetJointexpensesOfAnJointaccountBetween(id, from, to string) ([]*Jointexpense, error) {
+ q := `
+ SELECT a.id, a.jointaccount_id, a.value, a.type_jointexpense, a.jointexpense_date, a.created_at, a.updated_at, a.libelle
+ FROM public.jointexpense a
+ WHERE a.jointaccount_id = $1
+ AND a.jointexpense_date BETWEEN $2 and $3
+ `
+ rows, err := db.Session.Query(q, id, from, to)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ es := make([]*Jointexpense, 0)
+ for rows.Next() {
+ e := Jointexpense{}
+ err := rows.Scan(&e.ID, &e.JointjointaccountId, &e.Value, &e.TypeJointexpense, &e.JointexpenseDate, &e.CreatedAt, &e.UpdatedAt, &e.Libelle)
+ if err != nil {
+ return nil, err
+ }
+ es = append(es, &e)
+ }
+ return es, nil
+}
+
+func (db Database) GetAllJointexpensesOfAnJointaccount(id string) ([]*Jointexpense, error) {
+ q := `
+ SELECT a.id, a.jointaccount_id, a.value, a.type_jointexpense, a.jointexpense_date, a.created_at, a.updated_at, a.libelle
+ FROM public.jointexpense a
+ WHERE a.jointaccount_id = $1
+ `
+ rows, err := db.Session.Query(q, id)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ es := make([]*Jointexpense, 0)
+ for rows.Next() {
+ e := Jointexpense{}
+ err := rows.Scan(&e.ID, &e.JointaccountId, &e.Value, &e.TypeJointexpense, &e.JointexpenseDate, &e.CreatedAt, &e.UpdatedAt, &e.Libelle)
+ if err != nil {
+ return nil, err
+ }
+ es = append(es, &e)
+ }
+ return es, nil
+}
+
+func NewDatabase(db *postgresql.DatabasePostgreSQL) *Database {
+ return &Database{db}
+}
diff --git a/internal/jointexpense/handler.go b/internal/jointexpense/handler.go
new file mode 100644
index 0000000..65f5848
--- /dev/null
+++ b/internal/jointexpense/handler.go
@@ -0,0 +1,132 @@
+package jointexpense
+
+import (
+ "encoding/csv"
+ "net/http"
+ "nos-comptes/handler"
+ "nos-comptes/internal/jointaccount"
+ "nos-comptes/internal/storage/dao/postgresql"
+ "nos-comptes/internal/storage/model"
+ "nos-comptes/internal/storage/validators"
+ "nos-comptes/internal/utils"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Context struct {
+ service *Service
+ db *Database
+ jointaccountService *jointaccount.Service
+ *handler.Context
+}
+
+func (c *Context) ImportJointexpenseFromCSV(gc *gin.Context) {
+}
+func (c *Context) CreateAnJointexpense(gc *gin.Context) {
+ jointaccountID := gc.Param("jointaccountId")
+ userId := gc.Param("userId")
+ csvHeaderFile, err := gc.FormFile("attachment")
+ if err != nil {
+ utils.GetLogger().Info(err)
+ utils.JSONErrorWithMessage(gc.Writer, model.ErrInternalServer, err.Error())
+ return
+ }
+ if err == nil {
+ csvFile, err := csvHeaderFile.Open()
+ if err != nil {
+ utils.GetLogger().Info(err)
+ utils.JSONErrorWithMessage(gc.Writer, model.ErrInternalServer, err.Error())
+ return
+ }
+ csvr := csv.NewReader(csvFile)
+ csvr.FieldsPerRecord = -1
+ csvr.Comma = ';'
+ filedata, err := csvr.ReadAll()
+
+ jointaccount, err := c.jointaccountService.GetASpecificJointaccountForUser(userId, jointaccountID)
+ if err != nil {
+ utils.GetLogger().Info(err)
+ utils.JSONErrorWithMessage(gc.Writer, model.ErrInternalServer, err.Error())
+ return
+ }
+ err = c.service.ProcessCSVFile(filedata, jointaccount)
+ if err != nil {
+ utils.JSONErrorWithMessage(gc.Writer, model.ErrInternalServer, err.Error())
+ return
+ }
+ return
+ }
+ var jointexpense Jointexpense
+ var jointexpenseEditable JointexpenseEditable
+ if err := gc.BindJSON(&jointexpenseEditable); err != nil {
+ utils.JSONError(gc.Writer, validators.NewDataValidationAPIError(err))
+ return
+ }
+ jointexpense = Jointexpense{JointexpenseEditable: jointexpenseEditable, JointaccountId: jointaccountID}
+ err = c.service.CreateJointexpense(&jointexpense)
+ if err != nil {
+ utils.GetLogger().Info(err)
+ utils.JSONErrorWithMessage(gc.Writer, model.ErrInternalServer, err.Error())
+ return
+ }
+ utils.JSON(gc.Writer, http.StatusCreated, jointexpense)
+}
+
+func (c *Context) DeleteJointexpense(gc *gin.Context) {
+
+}
+
+func (c *Context) GetAllJointexpenses(gc *gin.Context) {
+ jointaccountId := gc.Param("jointaccountId")
+ from := gc.Query("from")
+ to := gc.Query("to")
+ var jointexpenses []*Jointexpense
+ var err error
+ if from != "" || to != "" {
+ if to == "" {
+ fromParsed, err := time.Parse("2006-01-02", from)
+ if err == nil {
+ to = time.Now().Format("2006-01-02")
+ } else {
+ to = fromParsed.AddDate(0, 1, 0).Format("2006-01-02")
+ }
+ }
+ if from == "" {
+ toParsed, err := time.Parse("2006-01-02", to)
+ if err == nil {
+ from = "1900-01-01"
+ } else {
+ from = toParsed.AddDate(0, -1, 0).Format("2006-01-02")
+ }
+ }
+ jointexpenses, err = c.service.GetJointexpensesOfAnJointaccountBetween(jointaccountId, from, to)
+ } else {
+ jointexpenses, err = c.service.GetAllJointexpensesOfAnJointaccount(jointaccountId)
+ }
+ if e, ok := err.(*model.APIError); ok {
+ utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetAllJointexpenses: get jointexpenses")
+ utils.JSONErrorWithMessage(gc.Writer, *e, e.Description)
+ } else if err != nil {
+ utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get jointexpenses")
+ utils.JSONError(gc.Writer, model.ErrInternalServer)
+ return
+ }
+
+ if len(jointexpenses) == 0 {
+ utils.JSON(gc.Writer, http.StatusNoContent, nil)
+ } else {
+ utils.JSON(gc.Writer, http.StatusOK, jointexpenses)
+ }
+}
+
+func (c *Context) GetAnJointexpenses(context *gin.Context) {
+
+}
+
+func NewHandler(ctx *handler.Context, db *postgresql.DatabasePostgreSQL) *Context {
+ database := NewDatabase(db)
+ service := NewService(database)
+ jointaccountService := jointaccount.NewService(jointaccount.NewDatabase(db))
+ return &Context{service: service, db: database, jointaccountService: jointaccountService, Context: ctx}
+}
diff --git a/internal/jointexpense/model.go b/internal/jointexpense/model.go
new file mode 100644
index 0000000..beb1845
--- /dev/null
+++ b/internal/jointexpense/model.go
@@ -0,0 +1,18 @@
+package jointexpense
+
+import "time"
+
+type Jointexpense struct {
+ JointexpenseEditable
+ JointaccountId string `json:"jointaccountId,omitempty"`
+}
+
+type JointexpenseEditable struct {
+ ID string `json:"id,omitempty"`
+ Value float32 `json:"value"`
+ Libelle string `json:"libelle"`
+ TypeJointexpense string `json:"typeJointexpense"`
+ JointexpenseDate time.Time `json:"jointexpenseDate,omitempty"`
+ CreatedAt *time.Time `json:"createdAt,omitempty"`
+ UpdatedAt *time.Time `json:"updatedAt,omitempty"`
+}
diff --git a/internal/jointexpense/service.go b/internal/jointexpense/service.go
new file mode 100644
index 0000000..4559e14
--- /dev/null
+++ b/internal/jointexpense/service.go
@@ -0,0 +1,120 @@
+package jointexpense
+
+import (
+ "nos-comptes/internal/jointaccount"
+ "nos-comptes/internal/storage/dao"
+ "nos-comptes/internal/storage/model"
+ "nos-comptes/internal/utils"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type Service struct {
+ db *Database
+}
+
+func (s Service) GetJointexpensesOfAnJointaccountBetween(jointaccountId, from, to string) ([]*Jointexpense, error) {
+ jointexpenses, err := s.db.GetJointexpensesOfAnJointaccountBetween(jointaccountId, from, to)
+ utils.GetLogger().Info(err)
+ if e, ok := err.(*dao.Error); ok {
+ switch {
+ case e.Type == dao.ErrTypeNotFound:
+ return nil, &model.ErrNotFound
+ default:
+ return nil, &model.ErrInternalServer
+ }
+ } else if err != nil {
+ return nil, &model.ErrInternalServer
+ }
+
+ if jointexpenses == nil {
+ return nil, &model.ErrNotFound
+ }
+ return jointexpenses, nil
+}
+
+func (s Service) GetAllJointexpensesOfAnJointaccount(jointaccountId string) ([]*Jointexpense, error) {
+ jointexpenses, err := s.db.GetAllJointexpensesOfAnJointaccount(jointaccountId)
+ utils.GetLogger().Info(err)
+ if e, ok := err.(*dao.Error); ok {
+ switch {
+ case e.Type == dao.ErrTypeNotFound:
+ return nil, &model.ErrNotFound
+ default:
+ return nil, &model.ErrInternalServer
+ }
+ } else if err != nil {
+ return nil, &model.ErrInternalServer
+ }
+
+ if jointexpenses == nil {
+ return nil, &model.ErrNotFound
+ }
+ return jointexpenses, nil
+}
+
+func (s Service) CreateJointexpense(jointexpense *Jointexpense) error {
+
+ return s.db.CreateJointexpense(jointexpense)
+}
+
+func (s Service) ProcessCSVFile(filedata [][]string, jointaccount *jointaccount.Jointaccount) error {
+ switch jointaccount.Provider {
+ case "caisse-epargne":
+ return s.processCaisseEpargne(filedata, jointaccount)
+ case "boursorama":
+ return s.processBoursorama(filedata, jointaccount)
+ case "bnp":
+ return s.processBnp(filedata, jointaccount)
+ default:
+ return nil
+ }
+
+}
+
+func (s Service) processCaisseEpargne(filedata [][]string, jointaccount *jointaccount.Jointaccount) error {
+ for _, val := range filedata[4:] {
+ jointexpenseDate, err := time.Parse("02/01/06", val[0])
+ if err != nil {
+ utils.GetLogger().Info(err)
+ continue
+ }
+ amount := val[3]
+ typeJointexpense := "D"
+ if amount == "" {
+ amount = val[4]
+ typeJointexpense = "C"
+ }
+ amountParsed, err := strconv.ParseFloat(strings.Trim(strings.ReplaceAll(amount, ",", "."), "+"), 32)
+ if err != nil {
+ utils.GetLogger().Info(err)
+ continue
+ }
+ jointexpense := &Jointexpense{
+ JointexpenseEditable: JointexpenseEditable{
+ Value: float32(amountParsed),
+ Libelle: val[2],
+ TypeJointexpense: typeJointexpense,
+ JointexpenseDate: jointexpenseDate,
+ },
+ JointaccountId: jointaccount.ID,
+ }
+ s.CreateJointexpense(jointexpense)
+ utils.GetLogger().Info(val)
+ }
+
+ return nil
+}
+
+func (s Service) processBoursorama(filedata [][]string, jointaccount *jointaccount.Jointaccount) error {
+ return nil
+}
+
+func (s Service) processBnp(filedata [][]string, jointaccount *jointaccount.Jointaccount) error {
+ return nil
+}
+
+func NewService(database *Database) *Service {
+ return &Service{db: database}
+}
diff --git a/liquibase/changelogs/changelog-master.xml b/liquibase/changelogs/changelog-master.xml
index 668241a..dcaa241 100644
--- a/liquibase/changelogs/changelog-master.xml
+++ b/liquibase/changelogs/changelog-master.xml
@@ -8,4 +8,6 @@
+
+
diff --git a/liquibase/changelogs/changeset/create-jointaccount.xml b/liquibase/changelogs/changeset/create-jointaccount.xml
new file mode 100644
index 0000000..ed1b101
--- /dev/null
+++ b/liquibase/changelogs/changeset/create-jointaccount.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/liquibase/changelogs/changeset/create-jointexpenses.xml b/liquibase/changelogs/changeset/create-jointexpenses.xml
new file mode 100644
index 0000000..2f61c16
--- /dev/null
+++ b/liquibase/changelogs/changeset/create-jointexpenses.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+