mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'dev/teguh' into 'feat/BE/Sprint-6'
[FEAT/BE][US#277, 280/TASK#290,291,294,295] : Adjust Schema Database table expense and adjust expense API, and finishing module project budgets See merge request mbugroup/lti-api!80
This commit is contained in:
@@ -9,6 +9,7 @@ require (
|
|||||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.2
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.2
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.92.1
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.92.1
|
||||||
github.com/bytedance/sonic v1.12.1
|
github.com/bytedance/sonic v1.12.1
|
||||||
|
github.com/glebarez/sqlite v1.11.0
|
||||||
github.com/go-playground/validator/v10 v10.27.0
|
github.com/go-playground/validator/v10 v10.27.0
|
||||||
github.com/gofiber/contrib/jwt v1.0.10
|
github.com/gofiber/contrib/jwt v1.0.10
|
||||||
github.com/gofiber/fiber/v2 v2.52.5
|
github.com/gofiber/fiber/v2 v2.52.5
|
||||||
@@ -45,8 +46,10 @@ require (
|
|||||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
|
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
@@ -70,6 +73,7 @@ require (
|
|||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
github.com/philhofer/fwd v1.1.2 // indirect
|
github.com/philhofer/fwd v1.1.2 // indirect
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
@@ -94,4 +98,8 @@ require (
|
|||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
modernc.org/libc v1.22.5 // indirect
|
||||||
|
modernc.org/mathutil v1.5.0 // indirect
|
||||||
|
modernc.org/memory v1.5.0 // indirect
|
||||||
|
modernc.org/sqlite v1.23.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -65,12 +65,18 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
|||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
|
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
|
||||||
|
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
|
||||||
|
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||||
|
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
@@ -88,6 +94,8 @@ github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17w
|
|||||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||||
|
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
@@ -184,6 +192,9 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
|||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
|
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
|
||||||
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
@@ -344,4 +355,12 @@ gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
|
|||||||
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||||
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
|
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
|
||||||
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||||
|
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
|
||||||
|
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||||
|
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||||
|
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||||
|
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||||
|
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||||
|
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
|
||||||
|
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ type ProductWarehouse struct {
|
|||||||
Quantity float64 `gorm:"column:qty;type:numeric(15,3);default:0"`
|
Quantity float64 `gorm:"column:qty;type:numeric(15,3);default:0"`
|
||||||
|
|
||||||
// Relations
|
// Relations
|
||||||
Product Product `gorm:"foreignKey:ProductId;references:Id"`
|
Product Product `gorm:"foreignKey:ProductId;references:Id"`
|
||||||
Warehouse Warehouse `gorm:"foreignKey:WarehouseId;references:Id"`
|
Warehouse Warehouse `gorm:"foreignKey:WarehouseId;references:Id"`
|
||||||
StockLogs []StockLog `gorm:"foreignKey:ProductWarehouseId;references:Id"`
|
ProjectFlockKandang *ProjectFlockKandang `gorm:"foreignKey:ProjectFlockKandangId;references:Id"`
|
||||||
|
StockLogs []StockLog `gorm:"foreignKey:ProductWarehouseId;references:Id"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ProjectBudget struct {
|
type ProjectBudget struct {
|
||||||
Id uint `gorm:"primaryKey"`
|
Id uint `gorm:"primaryKey"`
|
||||||
Qty float64 `gorm:"type:numeric(15,3);not null"`
|
ProjectFlockId uint `gorm:"not null"`
|
||||||
Price float64 `gorm:"type:numeric(15,3);not null"`
|
NonstockId uint `gorm:"not null"`
|
||||||
CreatedAt time.Time `gorm:"autoCreateTime"`
|
Qty float64 `gorm:"type:numeric(15,3);not null"`
|
||||||
|
Price float64 `gorm:"type:numeric(15,3);not null"`
|
||||||
|
CreatedAt time.Time `gorm:"autoCreateTime"`
|
||||||
|
|
||||||
Nonstock *Nonstock `gorm:"foreignKey:Id;references:Id"`
|
Nonstock *Nonstock `gorm:"foreignKey:NonstockId;references:Id"`
|
||||||
ProjectFlock *ProjectFlock `gorm:"foreignKey:Id;references:Id"`
|
ProjectFlock *ProjectFlock `gorm:"foreignKey:ProjectFlockId;references:Id"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type ProjectFlock struct {
|
|||||||
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
||||||
Kandangs []Kandang `gorm:"many2many:project_flock_kandangs;joinTableForeignKey:project_flock_id;joinTableReferences:kandang_id" json:"kandangs,omitempty"`
|
Kandangs []Kandang `gorm:"many2many:project_flock_kandangs;joinTableForeignKey:project_flock_id;joinTableReferences:kandang_id" json:"kandangs,omitempty"`
|
||||||
KandangHistory []ProjectFlockKandang `gorm:"foreignKey:ProjectFlockId;references:Id" json:"-"`
|
KandangHistory []ProjectFlockKandang `gorm:"foreignKey:ProjectFlockId;references:Id" json:"-"`
|
||||||
|
Budgets []ProjectBudget `gorm:"foreignKey:ProjectFlockId;references:Id" json:"-"`
|
||||||
|
|
||||||
LatestApproval *Approval `gorm:"-" json:"-"`
|
LatestApproval *Approval `gorm:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,28 @@ func (u *ClosingController) GetAll(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ClosingController) GetOne(c *fiber.Ctx) error {
|
||||||
|
param := c.Params("id")
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(param)
|
||||||
|
if err != nil || id <= 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid id")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := u.ClosingService.GetProjectFlockByID(c, uint(id))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.Success{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Retrieved closing information successfully",
|
||||||
|
Data: result,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (u *ClosingController) GetClosingSummary(c *fiber.Ctx) error {
|
func (u *ClosingController) GetClosingSummary(c *fiber.Ctx) error {
|
||||||
param := c.Params("projectFlockId")
|
param := c.Params("projectFlockId")
|
||||||
|
|
||||||
@@ -74,3 +96,30 @@ func (u *ClosingController) GetClosingSummary(c *fiber.Ctx) error {
|
|||||||
Data: result,
|
Data: result,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ClosingController) GetPenjualan(c *fiber.Ctx) error {
|
||||||
|
param := c.Params("project_flock_id")
|
||||||
|
|
||||||
|
projectFlockID, err := strconv.Atoi(param)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Project Flock Id")
|
||||||
|
}
|
||||||
|
|
||||||
|
projectFlock, err := u.ClosingService.GetProjectFlockByID(c, uint(projectFlockID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := u.ClosingService.GetPenjualan(c, uint(projectFlockID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.Success{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Get closing penjualan successfully",
|
||||||
|
Data: dto.ToPenjualanRealisasiResponseDTO(projectFlock.Category, uint(projectFlockID), result),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
|
deliveryOrdersDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/dto"
|
||||||
|
customerDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers/dto"
|
||||||
|
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
||||||
|
productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// === Response DTO ===
|
||||||
|
|
||||||
|
type SalesDTO struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
RealizationDate time.Time `json:"realization_date"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
DoNumber string `json:"do_number"`
|
||||||
|
Product *productDTO.ProductRelationDTO `json:"product,omitempty"`
|
||||||
|
Customer *customerDTO.CustomerRelationDTO `json:"customer,omitempty"`
|
||||||
|
Qty float64 `json:"qty"`
|
||||||
|
Weight float64 `json:"weight"`
|
||||||
|
AvgWeight float64 `json:"avg_weight"`
|
||||||
|
Price float64 `json:"price"`
|
||||||
|
TotalPrice float64 `json:"total_price"`
|
||||||
|
Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"`
|
||||||
|
PaymentStatus string `json:"payment_status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PenjualanRealisasiResponseDTO struct {
|
||||||
|
ProjectType string `json:"project_type"`
|
||||||
|
FlockId uint `json:"flock_id"`
|
||||||
|
Period int `json:"period"`
|
||||||
|
Sales []SalesDTO `json:"sales"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Mapper Functions ===
|
||||||
|
|
||||||
|
func ToSalesDTO(e entity.MarketingDeliveryProduct) SalesDTO {
|
||||||
|
|
||||||
|
// todo: usia ayam masih dummy
|
||||||
|
age := 0
|
||||||
|
|
||||||
|
var product *productDTO.ProductRelationDTO
|
||||||
|
if e.MarketingProduct.ProductWarehouse.Product.Id != 0 {
|
||||||
|
mapped := productDTO.ToProductRelationDTO(e.MarketingProduct.ProductWarehouse.Product)
|
||||||
|
product = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
var customer *customerDTO.CustomerRelationDTO
|
||||||
|
if e.MarketingProduct.Marketing.Customer.Id != 0 {
|
||||||
|
mapped := customerDTO.ToCustomerRelationDTO(e.MarketingProduct.Marketing.Customer)
|
||||||
|
customer = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
var kandang *kandangDTO.KandangRelationDTO
|
||||||
|
if e.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil && e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang.Id != 0 {
|
||||||
|
mapped := kandangDTO.ToKandangRelationDTO(e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang)
|
||||||
|
kandang = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
doNumber := deliveryOrdersDTO.GenerateDeliveryOrderNumber(e.MarketingProduct.Marketing.SoNumber, e.DeliveryDate, e.MarketingProduct.ProductWarehouse.Warehouse.Id)
|
||||||
|
|
||||||
|
return SalesDTO{
|
||||||
|
Id: e.Id,
|
||||||
|
RealizationDate: *e.DeliveryDate,
|
||||||
|
Age: age,
|
||||||
|
DoNumber: doNumber,
|
||||||
|
Product: product,
|
||||||
|
Customer: customer,
|
||||||
|
Qty: e.Qty,
|
||||||
|
Weight: e.TotalWeight,
|
||||||
|
AvgWeight: e.AvgWeight,
|
||||||
|
Price: e.UnitPrice,
|
||||||
|
TotalPrice: e.TotalPrice,
|
||||||
|
Kandang: kandang,
|
||||||
|
PaymentStatus: "Paid",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToSalesDTOs(e []entity.MarketingDeliveryProduct) []SalesDTO {
|
||||||
|
result := make([]SalesDTO, len(e))
|
||||||
|
for i, r := range e {
|
||||||
|
result[i] = ToSalesDTO(r)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToPenjualanRealisasiResponseDTO(projectType string, projectFlockID uint, e []entity.MarketingDeliveryProduct) PenjualanRealisasiResponseDTO {
|
||||||
|
period := extractPeriodFromRealisasi(e)
|
||||||
|
return PenjualanRealisasiResponseDTO{
|
||||||
|
ProjectType: projectType,
|
||||||
|
FlockId: projectFlockID,
|
||||||
|
Period: period,
|
||||||
|
Sales: ToSalesDTOs(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractPeriodFromRealisasi(realisasi []entity.MarketingDeliveryProduct) int {
|
||||||
|
if len(realisasi) > 0 {
|
||||||
|
for _, item := range realisasi {
|
||||||
|
if item.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil {
|
||||||
|
return item.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Period
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@@ -9,6 +9,9 @@ import (
|
|||||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
rClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
rClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
||||||
sClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/services"
|
sClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/services"
|
||||||
|
rMarketings "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
||||||
|
rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
|
|
||||||
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
|
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
|
||||||
sUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
sUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
)
|
)
|
||||||
@@ -18,11 +21,13 @@ type ClosingModule struct{}
|
|||||||
func (ClosingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
|
func (ClosingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
|
||||||
closingRepo := rClosing.NewClosingRepository(db)
|
closingRepo := rClosing.NewClosingRepository(db)
|
||||||
userRepo := rUser.NewUserRepository(db)
|
userRepo := rUser.NewUserRepository(db)
|
||||||
|
projectFlockRepo := rProjectFlock.NewProjectflockRepository(db)
|
||||||
|
marketingRepo := rMarketings.NewMarketingRepository(db)
|
||||||
|
marketingDeliveryProductRepo := rMarketings.NewMarketingDeliveryProductRepository(db)
|
||||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||||
approvalService := commonSvc.NewApprovalService(approvalRepo)
|
approvalService := commonSvc.NewApprovalService(approvalRepo)
|
||||||
|
|
||||||
closingService := sClosing.NewClosingService(closingRepo, approvalService, validate)
|
closingService := sClosing.NewClosingService(closingRepo, projectFlockRepo, marketingRepo, marketingDeliveryProductRepo, approvalService, validate)
|
||||||
userService := sUser.NewUserService(userRepo, validate)
|
userService := sUser.NewUserService(userRepo, validate)
|
||||||
|
|
||||||
ClosingRoutes(router, userService, closingService)
|
ClosingRoutes(router, userService, closingService)
|
||||||
|
|||||||
@@ -21,5 +21,6 @@ func ClosingRoutes(v1 fiber.Router, u user.UserService, s closing.ClosingService
|
|||||||
// route.Delete("/:id", m.Auth(u), ctrl.DeleteOne)
|
// route.Delete("/:id", m.Auth(u), ctrl.DeleteOne)
|
||||||
|
|
||||||
route.Get("/", ctrl.GetAll)
|
route.Get("/", ctrl.GetAll)
|
||||||
|
route.Get("/:project_flock_id/penjualan", ctrl.GetPenjualan)
|
||||||
route.Get("/:projectFlockId", ctrl.GetClosingSummary)
|
route.Get("/:projectFlockId", ctrl.GetClosingSummary)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import (
|
|||||||
"gitlab.com/mbugroup/lti-api.git/internal/modules/closings/dto"
|
"gitlab.com/mbugroup/lti-api.git/internal/modules/closings/dto"
|
||||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
||||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/validations"
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/validations"
|
||||||
|
marketingDeliveryProductRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
||||||
|
marketingRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
||||||
|
projectflockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||||
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
|
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
|
||||||
|
|
||||||
@@ -20,22 +23,30 @@ import (
|
|||||||
|
|
||||||
type ClosingService interface {
|
type ClosingService interface {
|
||||||
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, error)
|
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, error)
|
||||||
|
GetProjectFlockByID(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, error)
|
||||||
|
GetPenjualan(ctx *fiber.Ctx, projectFlockID uint) ([]entity.MarketingDeliveryProduct, error)
|
||||||
GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error)
|
GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type closingService struct {
|
type closingService struct {
|
||||||
Log *logrus.Logger
|
Log *logrus.Logger
|
||||||
Validate *validator.Validate
|
Validate *validator.Validate
|
||||||
Repository repository.ClosingRepository
|
Repository repository.ClosingRepository
|
||||||
ApprovalSvc commonSvc.ApprovalService
|
ProjectFlockRepo projectflockRepository.ProjectflockRepository
|
||||||
|
MarketingRepo marketingRepository.MarketingRepository
|
||||||
|
MarketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository
|
||||||
|
ApprovalSvc commonSvc.ApprovalService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClosingService(repo repository.ClosingRepository, approvalSvc commonSvc.ApprovalService, validate *validator.Validate) ClosingService {
|
func NewClosingService(repo repository.ClosingRepository, projectFlockRepo projectflockRepository.ProjectflockRepository, marketingRepo marketingRepository.MarketingRepository, marketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository, approvalSvc commonSvc.ApprovalService, validate *validator.Validate) ClosingService {
|
||||||
return &closingService{
|
return &closingService{
|
||||||
Log: utils.Log,
|
Log: utils.Log,
|
||||||
Validate: validate,
|
Validate: validate,
|
||||||
Repository: repo,
|
Repository: repo,
|
||||||
ApprovalSvc: approvalSvc,
|
ProjectFlockRepo: projectFlockRepo,
|
||||||
|
MarketingRepo: marketingRepo,
|
||||||
|
MarketingDeliveryProductRepo: marketingDeliveryProductRepo,
|
||||||
|
ApprovalSvc: approvalSvc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +82,43 @@ func (s closingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity
|
|||||||
return closings, total, nil
|
return closings, total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s closingService) GetProjectFlockByID(c *fiber.Ctx, id uint) (*entity.ProjectFlock, error) {
|
||||||
|
projectFlock, err := s.ProjectFlockRepo.GetByID(c.Context(), id, s.withRelations)
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Project Flock not found")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return projectFlock, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint) ([]entity.MarketingDeliveryProduct, error) {
|
||||||
|
|
||||||
|
realisasi, err := s.MarketingDeliveryProductRepo.GetDeliveryProductsByProjectFlockID(c.Context(), projectFlockID, func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.
|
||||||
|
Preload("MarketingProduct").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse.Product").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse.Product.Uom").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse.Product.Flags").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse.Warehouse").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang").
|
||||||
|
Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang").
|
||||||
|
Preload("MarketingProduct.Marketing").
|
||||||
|
Preload("MarketingProduct.Marketing.Customer").
|
||||||
|
Order("marketing_delivery_products.delivery_date DESC")
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(realisasi) == 0 {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Penjualan realisasi not found")
|
||||||
|
}
|
||||||
|
return realisasi, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error) {
|
func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error) {
|
||||||
if projectFlockID == 0 {
|
if projectFlockID == 0 {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||||
|
|||||||
@@ -151,12 +151,16 @@ func (u *ExpenseController) UpdateOne(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req.Documents = form.File["documents"]
|
req.Documents = form.File["documents"]
|
||||||
if transactionDate := c.FormValue("transaction_date"); transactionDate != "" {
|
|
||||||
|
transactionDate := c.FormValue("transaction_date")
|
||||||
|
if transactionDate != "" {
|
||||||
req.TransactionDate = &transactionDate
|
req.TransactionDate = &transactionDate
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryVal := c.FormValue("category")
|
categoryVal := c.FormValue("category")
|
||||||
req.Category = &categoryVal
|
if categoryVal != "" {
|
||||||
|
req.Category = &categoryVal
|
||||||
|
}
|
||||||
|
|
||||||
supplierIDVal := c.FormValue("supplier_id")
|
supplierIDVal := c.FormValue("supplier_id")
|
||||||
if supplierIDVal != "" {
|
if supplierIDVal != "" {
|
||||||
@@ -312,13 +316,18 @@ func (u *ExpenseController) UpdateRealization(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
req.Documents = form.File["documents"]
|
req.Documents = form.File["documents"]
|
||||||
|
|
||||||
req.RealizationDate = c.FormValue("realization_date")
|
realizationDate := c.FormValue("realization_date")
|
||||||
|
if realizationDate != "" {
|
||||||
|
req.RealizationDate = &realizationDate
|
||||||
|
}
|
||||||
|
|
||||||
realizationsJSON := c.FormValue("realizations")
|
realizationsJSON := c.FormValue("realizations")
|
||||||
if realizationsJSON != "" {
|
if realizationsJSON != "" {
|
||||||
if err := json.Unmarshal([]byte(realizationsJSON), &req.Realizations); err != nil {
|
var realizations []validation.RealizationItem
|
||||||
|
if err := json.Unmarshal([]byte(realizationsJSON), &realizations); err != nil {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Invalid realizations JSON: %v", err))
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Invalid realizations JSON: %v", err))
|
||||||
}
|
}
|
||||||
|
req.Realizations = &realizations
|
||||||
}
|
}
|
||||||
|
|
||||||
expense, err := u.ExpenseService.UpdateRealization(c, uint(id), &req)
|
expense, err := u.ExpenseService.UpdateRealization(c, uint(id), &req)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ func ExpenseRoutes(v1 fiber.Router, u user.UserService, s expense.ExpenseService
|
|||||||
|
|
||||||
route := v1.Group("/expenses")
|
route := v1.Group("/expenses")
|
||||||
route.Use(m.Auth(u))
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
|
// route.Use(m.Auth(u))
|
||||||
// route.Get("/", m.Auth(u), ctrl.GetAll)
|
// route.Get("/", m.Auth(u), ctrl.GetAll)
|
||||||
// route.Post("/", m.Auth(u), ctrl.CreateOne)
|
// route.Post("/", m.Auth(u), ctrl.CreateOne)
|
||||||
// route.Get("/:id", m.Auth(u), ctrl.GetOne)
|
// route.Get("/:id", m.Auth(u), ctrl.GetOne)
|
||||||
|
|||||||
@@ -732,10 +732,10 @@ func (s *expenseService) UpdateRealization(c *fiber.Ctx, expenseID uint, req *va
|
|||||||
expenseRepoTx := repository.NewExpenseRepository(tx)
|
expenseRepoTx := repository.NewExpenseRepository(tx)
|
||||||
|
|
||||||
// Check if only updating documents
|
// Check if only updating documents
|
||||||
updateDataOnly := len(req.Realizations) == 0 && len(req.Documents) > 0
|
updateDataOnly := req.Realizations == nil && len(req.Documents) > 0
|
||||||
|
|
||||||
if len(req.Realizations) > 0 {
|
if req.Realizations != nil {
|
||||||
for _, realizationItem := range req.Realizations {
|
for _, realizationItem := range *req.Realizations {
|
||||||
|
|
||||||
expenseNonstockID := realizationItem.ExpenseNonstockID
|
expenseNonstockID := realizationItem.ExpenseNonstockID
|
||||||
|
|
||||||
@@ -770,6 +770,12 @@ func (s *expenseService) UpdateRealization(c *fiber.Ctx, expenseID uint, req *va
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.RealizationDate != nil {
|
||||||
|
if err := expenseRepoTx.PatchOne(c.Context(), expenseID, map[string]interface{}{"realization_date": *req.RealizationDate}, nil); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update realization date")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(req.Documents) > 0 {
|
if len(req.Documents) > 0 {
|
||||||
if err := s.processDocuments(c, expenseRepoTx, expenseID, req.Documents, true); err != nil {
|
if err := s.processDocuments(c, expenseRepoTx, expenseID, req.Documents, true); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Create struct {
|
type Create struct {
|
||||||
PoNumber string `form:"po_number" json:"po_number" validate:"omitempty,max=50"`
|
PoNumber string `form:"po_number" json:"po_number" validate:"omitempty,max=50"`
|
||||||
TransactionDate string `form:"transaction_date" json:"transaction_date" validate:"required,datetime=2006-01-02"`
|
TransactionDate string `form:"transaction_date" json:"transaction_date" validate:"required,datetime=2006-01-02"`
|
||||||
Category string `form:"category" json:"category" validate:"required,oneof=BOP NON-BOP"`
|
Category string `form:"category" json:"category" validate:"required,oneof=BOP NON-BOP"`
|
||||||
SupplierID uint64 `form:"supplier_id" json:"supplier_id" validate:"required,gt=0"`
|
SupplierID uint64 `form:"supplier_id" json:"supplier_id" validate:"required,gt=0"`
|
||||||
Documents []*multipart.FileHeader `form:"documents" json:"documents" validate:"omitempty,dive"`
|
Documents []*multipart.FileHeader `form:"documents" json:"documents" validate:"omitempty,dive"`
|
||||||
ExpenseNonstocks []ExpenseNonstock `form:"expense_nonstocks" json:"expense_nonstocks" validate:"required,min=1,dive"`
|
ExpenseNonstocks []ExpenseNonstock `form:"expense_nonstocks" json:"expense_nonstocks" validate:"required,min=1,dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,11 +26,11 @@ type CostItem struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Update struct {
|
type Update struct {
|
||||||
TransactionDate *string `form:"transaction_date" json:"transaction_date" validate:"omitempty,datetime=2006-01-02"`
|
TransactionDate *string `form:"transaction_date" json:"transaction_date" validate:"omitempty,datetime=2006-01-02"`
|
||||||
Category *string `form:"category" json:"category" validate:"omitempty,oneof=BOP NON-BOP"`
|
Category *string `form:"category" json:"category" validate:"omitempty,oneof=BOP NON-BOP"`
|
||||||
SupplierID *uint64 `form:"supplier_id" json:"supplier_id" validate:"omitempty,gt=0"`
|
SupplierID *uint64 `form:"supplier_id" json:"supplier_id" validate:"omitempty,gt=0"`
|
||||||
|
Documents []*multipart.FileHeader `form:"documents" json:"documents" validate:"omitempty,dive"`
|
||||||
ExpenseNonstocks *[]ExpenseNonstock `form:"expense_nonstocks" json:"expense_nonstocks" validate:"omitempty,min=1,dive"`
|
ExpenseNonstocks *[]ExpenseNonstock `form:"expense_nonstocks" json:"expense_nonstocks" validate:"omitempty,min=1,dive"`
|
||||||
Documents []*multipart.FileHeader `form:"documents" json:"documents" validate:"omitempty,dive"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query struct {
|
type Query struct {
|
||||||
@@ -46,9 +46,9 @@ type CreateRealization struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UpdateRealization struct {
|
type UpdateRealization struct {
|
||||||
RealizationDate string `form:"realization_date" json:"realization_date" validate:"omitempty,datetime=2006-01-02"`
|
RealizationDate *string `form:"realization_date" json:"realization_date" validate:"omitempty,datetime=2006-01-02"`
|
||||||
Documents []*multipart.FileHeader `form:"documents" json:"documents" validate:"omitempty,dive"`
|
Documents []*multipart.FileHeader `form:"documents" json:"documents" validate:"omitempty,dive"`
|
||||||
Realizations []RealizationItem `form:"realizations" json:"realizations" validate:"required,min=1,dive"`
|
Realizations *[]RealizationItem `form:"realizations" json:"realizations" validate:"omitempty,min=1,dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RealizationItem struct {
|
type RealizationItem struct {
|
||||||
|
|||||||
-51
@@ -1,51 +0,0 @@
|
|||||||
package repository
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MarketingDeliveryProductRepository interface {
|
|
||||||
repository.BaseRepository[entity.MarketingDeliveryProduct]
|
|
||||||
GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error)
|
|
||||||
GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type MarketingDeliveryProductRepositoryImpl struct {
|
|
||||||
*repository.BaseRepositoryImpl[entity.MarketingDeliveryProduct]
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMarketingDeliveryProductRepository(db *gorm.DB) MarketingDeliveryProductRepository {
|
|
||||||
return &MarketingDeliveryProductRepositoryImpl{
|
|
||||||
BaseRepositoryImpl: repository.NewBaseRepository[entity.MarketingDeliveryProduct](db),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error) {
|
|
||||||
var deliveryProduct entity.MarketingDeliveryProduct
|
|
||||||
if err := r.DB().WithContext(ctx).Where("marketing_product_id = ?", marketingProductID).First(&deliveryProduct).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &deliveryProduct, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error) {
|
|
||||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
|
||||||
|
|
||||||
// Raw query untuk mengambil delivery products berdasarkan marketing ID dengan preload MarketingProduct
|
|
||||||
// Filter: hanya ambil yang sudah memiliki delivery_date (delivery date tidak null)
|
|
||||||
if err := r.DB().WithContext(ctx).
|
|
||||||
Preload("MarketingProduct").
|
|
||||||
Joins("INNER JOIN marketing_products mp ON marketing_delivery_products.marketing_product_id = mp.id").
|
|
||||||
Where("mp.marketing_id = ?", marketingId).
|
|
||||||
Where("marketing_delivery_products.delivery_date IS NOT NULL").
|
|
||||||
Order("marketing_delivery_products.id ASC").
|
|
||||||
Find(&deliveryProducts).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return deliveryProducts, nil
|
|
||||||
}
|
|
||||||
@@ -44,7 +44,7 @@ func (s productWarehouseService) withRelations(db *gorm.DB) *gorm.DB {
|
|||||||
Preload("Warehouse.Location").
|
Preload("Warehouse.Location").
|
||||||
Preload("Warehouse.Area").
|
Preload("Warehouse.Area").
|
||||||
Preload("Warehouse.Kandang").
|
Preload("Warehouse.Kandang").
|
||||||
Preload("CreatedUser")
|
Preload("ProjectFlockKandang")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProductWarehouse, int64, error) {
|
func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProductWarehouse, int64, error) {
|
||||||
@@ -104,7 +104,7 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
|
|||||||
|
|
||||||
db = s.Repository.ApplyFlagsFilter(db, cleanFlags)
|
db = s.Repository.ApplyFlagsFilter(db, cleanFlags)
|
||||||
|
|
||||||
return db.Order("created_at DESC").Order("updated_at DESC")
|
return db.Order("product_warehouses.id DESC")
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -319,15 +319,20 @@ func groupDeliveryProducts(products []MarketingDeliveryProductDTO, soNumber stri
|
|||||||
})
|
})
|
||||||
|
|
||||||
for i := range groups {
|
for i := range groups {
|
||||||
if groups[i].DeliveryDate != nil {
|
groups[i].DoNumber = GenerateDeliveryOrderNumber(soNumber, groups[i].DeliveryDate, groups[i].Warehouse.Id)
|
||||||
dateStr := groups[i].DeliveryDate.Format("20060102")
|
|
||||||
groups[i].DoNumber = fmt.Sprintf("%s-%s-%d", soNumber, dateStr, groups[i].Warehouse.Id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateDeliveryOrderNumber(soNumber string, deliveryDate *time.Time, warehouseId uint) string {
|
||||||
|
dateStr := ""
|
||||||
|
if deliveryDate != nil {
|
||||||
|
dateStr = deliveryDate.Format("20060102")
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s-%s-%d", soNumber, dateStr, warehouseId)
|
||||||
|
}
|
||||||
|
|
||||||
func getVehicleNumber(e entity.MarketingProduct) string {
|
func getVehicleNumber(e entity.MarketingProduct) string {
|
||||||
if e.DeliveryProduct != nil && e.DeliveryProduct.VehicleNumber != "" {
|
if e.DeliveryProduct != nil && e.DeliveryProduct.VehicleNumber != "" {
|
||||||
return e.DeliveryProduct.VehicleNumber
|
return e.DeliveryProduct.VehicleNumber
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
rMarketingDeliveryProduct "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/marketing-delivery-products/repositories"
|
|
||||||
sDeliveryOrders "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/services"
|
sDeliveryOrders "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/services"
|
||||||
rMarketing "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
rMarketing "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
||||||
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
|
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
|
||||||
@@ -22,7 +21,7 @@ type DeliveryOrdersModule struct{}
|
|||||||
func (DeliveryOrdersModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
|
func (DeliveryOrdersModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
|
||||||
marketingRepo := rMarketing.NewMarketingRepository(db)
|
marketingRepo := rMarketing.NewMarketingRepository(db)
|
||||||
marketingProductRepo := rMarketing.NewMarketingProductRepository(db)
|
marketingProductRepo := rMarketing.NewMarketingProductRepository(db)
|
||||||
marketingDeliveryProductRepo := rMarketingDeliveryProduct.NewMarketingDeliveryProductRepository(db)
|
marketingDeliveryProductRepo := rMarketing.NewMarketingDeliveryProductRepository(db)
|
||||||
userRepo := rUser.NewUserRepository(db)
|
userRepo := rUser.NewUserRepository(db)
|
||||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||||
approvalSvc := commonSvc.NewApprovalService(approvalRepo)
|
approvalSvc := commonSvc.NewApprovalService(approvalRepo)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package delivery_orderss
|
package delivery_orderss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||||
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/controllers"
|
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/controllers"
|
||||||
deliveryOrders "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/services"
|
deliveryOrders "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/services"
|
||||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
@@ -17,6 +17,7 @@ func DeliveryOrdersRoutes(v1 fiber.Router, u user.UserService, s deliveryOrders.
|
|||||||
|
|
||||||
// Sisanya di group /delivery-orders
|
// Sisanya di group /delivery-orders
|
||||||
route := v1.Group("/delivery-orders")
|
route := v1.Group("/delivery-orders")
|
||||||
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
// route.Get("/", m.Auth(u), ctrl.GetAll)
|
// route.Get("/", m.Auth(u), ctrl.GetAll)
|
||||||
// route.Post("/", m.Auth(u), ctrl.CreateOne)
|
// route.Post("/", m.Auth(u), ctrl.CreateOne)
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ import (
|
|||||||
|
|
||||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
marketingDeliveryProductRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/marketing-delivery-products/repositories"
|
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||||
productWarehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
productWarehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/dto"
|
"gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/dto"
|
||||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/validations"
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/validations"
|
||||||
@@ -35,14 +34,14 @@ type deliveryOrdersService struct {
|
|||||||
Validate *validator.Validate
|
Validate *validator.Validate
|
||||||
MarketingRepo marketingRepo.MarketingRepository
|
MarketingRepo marketingRepo.MarketingRepository
|
||||||
MarketingProductRepo marketingRepo.MarketingProductRepository
|
MarketingProductRepo marketingRepo.MarketingProductRepository
|
||||||
MarketingDeliveryProductRepo marketingDeliveryProductRepo.MarketingDeliveryProductRepository
|
MarketingDeliveryProductRepo marketingRepo.MarketingDeliveryProductRepository
|
||||||
ApprovalSvc commonSvc.ApprovalService
|
ApprovalSvc commonSvc.ApprovalService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDeliveryOrdersService(
|
func NewDeliveryOrdersService(
|
||||||
marketingRepo marketingRepo.MarketingRepository,
|
marketingRepo marketingRepo.MarketingRepository,
|
||||||
marketingProductRepo marketingRepo.MarketingProductRepository,
|
marketingProductRepo marketingRepo.MarketingProductRepository,
|
||||||
marketingDeliveryProductRepo marketingDeliveryProductRepo.MarketingDeliveryProductRepository,
|
marketingDeliveryProductRepo marketingRepo.MarketingDeliveryProductRepository,
|
||||||
approvalSvc commonSvc.ApprovalService,
|
approvalSvc commonSvc.ApprovalService,
|
||||||
validate *validator.Validate,
|
validate *validator.Validate,
|
||||||
) DeliveryOrdersService {
|
) DeliveryOrdersService {
|
||||||
@@ -200,7 +199,7 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
|||||||
err = s.MarketingRepo.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
err = s.MarketingRepo.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||||
|
|
||||||
marketingProductRepositoryTx := marketingRepo.NewMarketingProductRepository(dbTransaction)
|
marketingProductRepositoryTx := marketingRepo.NewMarketingProductRepository(dbTransaction)
|
||||||
marketingDeliveryProductRepositoryTx := marketingDeliveryProductRepo.NewMarketingDeliveryProductRepository(dbTransaction)
|
marketingDeliveryProductRepositoryTx := marketingRepo.NewMarketingDeliveryProductRepository(dbTransaction)
|
||||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||||
|
|
||||||
allMarketingProducts, err := marketingProductRepositoryTx.GetByMarketingID(c.Context(), req.MarketingId)
|
allMarketingProducts, err := marketingProductRepositoryTx.GetByMarketingID(c.Context(), req.MarketingId)
|
||||||
@@ -259,7 +258,6 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
approvalAction := entity.ApprovalActionApproved
|
approvalAction := entity.ApprovalActionApproved
|
||||||
if _, err := approvalSvcTx.CreateApproval(
|
if _, err := approvalSvcTx.CreateApproval(
|
||||||
c.Context(),
|
c.Context(),
|
||||||
@@ -301,7 +299,7 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, i
|
|||||||
err := s.MarketingRepo.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
err := s.MarketingRepo.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||||
|
|
||||||
marketingProductRepositoryTx := marketingRepo.NewMarketingProductRepository(dbTransaction)
|
marketingProductRepositoryTx := marketingRepo.NewMarketingProductRepository(dbTransaction)
|
||||||
marketingDeliveryProductRepositoryTx := marketingDeliveryProductRepo.NewMarketingDeliveryProductRepository(dbTransaction)
|
marketingDeliveryProductRepositoryTx := marketingRepo.NewMarketingDeliveryProductRepository(dbTransaction)
|
||||||
|
|
||||||
allMarketingProducts, err := marketingProductRepositoryTx.GetByMarketingID(c.Context(), id)
|
allMarketingProducts, err := marketingProductRepositoryTx.GetByMarketingID(c.Context(), id)
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
|||||||
+55
@@ -1,6 +1,8 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -8,6 +10,9 @@ import (
|
|||||||
|
|
||||||
type MarketingDeliveryProductRepository interface {
|
type MarketingDeliveryProductRepository interface {
|
||||||
repository.BaseRepository[entity.MarketingDeliveryProduct]
|
repository.BaseRepository[entity.MarketingDeliveryProduct]
|
||||||
|
GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error)
|
||||||
|
GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error)
|
||||||
|
GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MarketingDeliveryProductRepositoryImpl struct {
|
type MarketingDeliveryProductRepositoryImpl struct {
|
||||||
@@ -19,3 +24,53 @@ func NewMarketingDeliveryProductRepository(db *gorm.DB) MarketingDeliveryProduct
|
|||||||
BaseRepositoryImpl: repository.NewBaseRepository[entity.MarketingDeliveryProduct](db),
|
BaseRepositoryImpl: repository.NewBaseRepository[entity.MarketingDeliveryProduct](db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *MarketingDeliveryProductRepositoryImpl) GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error) {
|
||||||
|
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||||
|
|
||||||
|
// JOIN digunakan untuk filter WHERE clause ke ProjectFlockID yang berada 3 level relasi atas
|
||||||
|
// Entity relations digunakan di Preload (callback) untuk load data, bukan untuk filter
|
||||||
|
db := r.DB().WithContext(ctx).
|
||||||
|
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||||
|
Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id").
|
||||||
|
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||||
|
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||||
|
Distinct("marketing_delivery_products.*")
|
||||||
|
|
||||||
|
if callback != nil {
|
||||||
|
db = callback(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Find(&deliveryProducts).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return deliveryProducts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error) {
|
||||||
|
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||||
|
|
||||||
|
// JOIN untuk filter by marketing_id yang ada di related table
|
||||||
|
db := r.DB().WithContext(ctx).
|
||||||
|
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||||
|
Where("marketing_products.marketing_id = ?", marketingId)
|
||||||
|
|
||||||
|
if err := db.Find(&deliveryProducts).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return deliveryProducts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error) {
|
||||||
|
var deliveryProduct entity.MarketingDeliveryProduct
|
||||||
|
|
||||||
|
if err := r.DB().WithContext(ctx).
|
||||||
|
Where("marketing_product_id = ?", marketingProductID).
|
||||||
|
First(&deliveryProduct).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &deliveryProduct, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package sales_orders
|
package sales_orders
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||||
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/controllers"
|
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/controllers"
|
||||||
salesOrders "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/services"
|
salesOrders "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/services"
|
||||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
@@ -14,6 +14,7 @@ func SalesOrdersRoutes(v1 fiber.Router, u user.UserService, s salesOrders.SalesO
|
|||||||
|
|
||||||
v1.Delete("/:id", ctrl.DeleteOne)
|
v1.Delete("/:id", ctrl.DeleteOne)
|
||||||
route := v1.Group("/sales-orders")
|
route := v1.Group("/sales-orders")
|
||||||
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
// route.Post("/", m.Auth(u), ctrl.CreateOne)
|
// route.Post("/", m.Auth(u), ctrl.CreateOne)
|
||||||
// route.Patch("/:id", m.Auth(u), ctrl.UpdateOne)
|
// route.Patch("/:id", m.Auth(u), ctrl.UpdateOne)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||||
rInvMarketingDeliveryProduct "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/marketing-delivery-products/repositories"
|
|
||||||
productWarehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
productWarehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
||||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/validations"
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/validations"
|
||||||
@@ -125,7 +124,7 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
|
|||||||
|
|
||||||
marketingRepoTx := repository.NewMarketingRepository(dbTransaction)
|
marketingRepoTx := repository.NewMarketingRepository(dbTransaction)
|
||||||
marketingProductRepoTx := repository.NewMarketingProductRepository(dbTransaction)
|
marketingProductRepoTx := repository.NewMarketingProductRepository(dbTransaction)
|
||||||
invDeliveryRepoTx := rInvMarketingDeliveryProduct.NewMarketingDeliveryProductRepository(dbTransaction)
|
invDeliveryRepoTx := repository.NewMarketingDeliveryProductRepository(dbTransaction)
|
||||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||||
|
|
||||||
marketing = &entity.Marketing{
|
marketing = &entity.Marketing{
|
||||||
@@ -220,7 +219,7 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
marketingRepoTx := repository.NewMarketingRepository(dbTransaction)
|
marketingRepoTx := repository.NewMarketingRepository(dbTransaction)
|
||||||
marketingProductRepoTx := repository.NewMarketingProductRepository(dbTransaction)
|
marketingProductRepoTx := repository.NewMarketingProductRepository(dbTransaction)
|
||||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||||
invDeliveryRepoTx := rInvMarketingDeliveryProduct.NewMarketingDeliveryProductRepository(dbTransaction)
|
invDeliveryRepoTx := repository.NewMarketingDeliveryProductRepository(dbTransaction)
|
||||||
|
|
||||||
updateBody := make(map[string]any)
|
updateBody := make(map[string]any)
|
||||||
if req.CustomerId != 0 {
|
if req.CustomerId != 0 {
|
||||||
@@ -527,7 +526,7 @@ func (s salesOrdersService) Approval(c *fiber.Ctx, req *validation.Approve) ([]e
|
|||||||
return updated, nil
|
return updated, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Context, marketingId uint, rp validation.CreateMarketingProduct, marketingProductRepo repository.MarketingProductRepository, invDeliveryRepo rInvMarketingDeliveryProduct.MarketingDeliveryProductRepository) error {
|
func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Context, marketingId uint, rp validation.CreateMarketingProduct, marketingProductRepo repository.MarketingProductRepository, invDeliveryRepo repository.MarketingDeliveryProductRepository) error {
|
||||||
|
|
||||||
marketingProduct := &entity.MarketingProduct{
|
marketingProduct := &entity.MarketingProduct{
|
||||||
MarketingId: marketingId,
|
MarketingId: marketingId,
|
||||||
|
|||||||
@@ -329,3 +329,29 @@ func (u *ProjectflockController) LookupProjectFlockKandang(c *fiber.Ctx) error {
|
|||||||
Message: "Get projectflock kandang successfully",
|
Message: "Get projectflock kandang successfully",
|
||||||
Data: dtoResult})
|
Data: dtoResult})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ProjectflockController) Resubmit(c *fiber.Ctx) error {
|
||||||
|
param := c.Params("id")
|
||||||
|
req := new(validation.Resubmit)
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(param)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Id")
|
||||||
|
}
|
||||||
|
if err := c.BodyParser(req); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := u.ProjectflockService.Resubmit(c, req, uint(id))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).
|
||||||
|
JSON(response.Success{
|
||||||
|
Code: fiber.StatusOK,
|
||||||
|
Status: "success",
|
||||||
|
Message: "Resubmit projectflock successfully",
|
||||||
|
Data: dto.ToProjectFlockListDTO(*result),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
||||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
||||||
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||||
|
nonstockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/dto"
|
||||||
|
|
||||||
// pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
// pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
||||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||||
@@ -24,15 +25,16 @@ type ProjectFlockRelationDTO struct {
|
|||||||
|
|
||||||
type ProjectFlockListDTO struct {
|
type ProjectFlockListDTO struct {
|
||||||
ProjectFlockRelationDTO
|
ProjectFlockRelationDTO
|
||||||
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
||||||
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
||||||
Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"`
|
Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"`
|
||||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user"`
|
ProjectBudgets []ProjectBudgetDTO `json:"project_budgets,omitempty"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedUser *userDTO.UserRelationDTO `json:"created_user"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KandangWithProjectFlockIdDTO struct {
|
type KandangWithProjectFlockIdDTO struct {
|
||||||
@@ -51,6 +53,13 @@ type KandangPeriodSummaryDTO struct {
|
|||||||
Period int `json:"period"`
|
Period int `json:"period"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProjectBudgetDTO struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Qty float64 `json:"qty"`
|
||||||
|
Price float64 `json:"price"`
|
||||||
|
Nonstock *nonstockDTO.NonstockRelationDTO `json:"nonstock,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectFlockListDTO {
|
func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectFlockListDTO {
|
||||||
var createdUser *userDTO.UserRelationDTO
|
var createdUser *userDTO.UserRelationDTO
|
||||||
if e.CreatedUser.Id != 0 {
|
if e.CreatedUser.Id != 0 {
|
||||||
@@ -110,6 +119,7 @@ func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectF
|
|||||||
ProjectFlockRelationDTO: createProjectFlockRelationDTO(e, period),
|
ProjectFlockRelationDTO: createProjectFlockRelationDTO(e, period),
|
||||||
Area: areaSummary,
|
Area: areaSummary,
|
||||||
Kandangs: kandangSummaries,
|
Kandangs: kandangSummaries,
|
||||||
|
ProjectBudgets: ToProjectBudgetDTOs(e.Budgets),
|
||||||
Category: e.Category,
|
Category: e.Category,
|
||||||
Fcr: fcrSummary,
|
Fcr: fcrSummary,
|
||||||
Location: locationSummary,
|
Location: locationSummary,
|
||||||
@@ -184,3 +194,26 @@ func createProjectFlockRelationDTO(e entity.ProjectFlock, period int) ProjectFlo
|
|||||||
FlockName: e.FlockName,
|
FlockName: e.FlockName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToProjectBudgetDTO(e entity.ProjectBudget) ProjectBudgetDTO {
|
||||||
|
var nonstockRef *nonstockDTO.NonstockRelationDTO
|
||||||
|
if e.Nonstock != nil && e.Nonstock.Id != 0 {
|
||||||
|
mapped := nonstockDTO.ToNonstockRelationDTO(*e.Nonstock)
|
||||||
|
nonstockRef = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProjectBudgetDTO{
|
||||||
|
Id: e.Id,
|
||||||
|
Qty: e.Qty,
|
||||||
|
Price: e.Price,
|
||||||
|
Nonstock: nonstockRef,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToProjectBudgetDTOs(e []entity.ProjectBudget) []ProjectBudgetDTO {
|
||||||
|
result := make([]ProjectBudgetDTO, len(e))
|
||||||
|
for i, r := range e {
|
||||||
|
result[i] = ToProjectBudgetDTO(r)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import (
|
|||||||
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||||
rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||||
rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
||||||
|
rNonstock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/repositories"
|
||||||
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
||||||
|
rProjectBudget "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
rProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
rProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
|
|
||||||
sProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services"
|
sProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services"
|
||||||
@@ -27,10 +29,12 @@ type ProjectflockModule struct{}
|
|||||||
func (ProjectflockModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
|
func (ProjectflockModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
|
||||||
flockRepo := rFlock.NewFlockRepository(db)
|
flockRepo := rFlock.NewFlockRepository(db)
|
||||||
kandangRepo := rKandang.NewKandangRepository(db)
|
kandangRepo := rKandang.NewKandangRepository(db)
|
||||||
|
nonstockRepo := rNonstock.NewNonstockRepository(db)
|
||||||
projectflockRepo := rProjectflock.NewProjectflockRepository(db)
|
projectflockRepo := rProjectflock.NewProjectflockRepository(db)
|
||||||
projectflockKandangRepo := rProjectflock.NewProjectFlockKandangRepository(db)
|
projectflockKandangRepo := rProjectflock.NewProjectFlockKandangRepository(db)
|
||||||
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
|
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
|
||||||
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
||||||
|
projectBudgetRepo := rProjectBudget.NewProjectBudgetRepository(db)
|
||||||
userRepo := rUser.NewUserRepository(db)
|
userRepo := rUser.NewUserRepository(db)
|
||||||
|
|
||||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||||
@@ -39,7 +43,7 @@ func (ProjectflockModule) RegisterRoutes(router fiber.Router, db *gorm.DB, valid
|
|||||||
panic(fmt.Sprintf("failed to register project flock approval workflow: %v", err))
|
panic(fmt.Sprintf("failed to register project flock approval workflow: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
projectflockService := sProjectflock.NewProjectflockService(projectflockRepo, flockRepo, kandangRepo, projectflockKandangRepo, warehouseRepo, productWarehouseRepo, approvalService, validate)
|
projectflockService := sProjectflock.NewProjectflockService(projectflockRepo, flockRepo, kandangRepo, projectflockKandangRepo, warehouseRepo, productWarehouseRepo, projectBudgetRepo, nonstockRepo, approvalService, validate)
|
||||||
userService := sUser.NewUserService(userRepo, validate)
|
userService := sUser.NewUserService(userRepo, validate)
|
||||||
|
|
||||||
ProjectflockRoutes(router, userService, projectflockService)
|
ProjectflockRoutes(router, userService, projectflockService)
|
||||||
|
|||||||
@@ -54,7 +54,10 @@ func (r *ProjectflockRepositoryImpl) WithDefaultRelations() func(*gorm.DB) *gorm
|
|||||||
Preload("Location").
|
Preload("Location").
|
||||||
Preload("Kandangs").
|
Preload("Kandangs").
|
||||||
Preload("KandangHistory").
|
Preload("KandangHistory").
|
||||||
Preload("KandangHistory.Kandang")
|
Preload("KandangHistory.Kandang").
|
||||||
|
Preload("Budgets").
|
||||||
|
Preload("Budgets.Nonstock").
|
||||||
|
Preload("Budgets.Nonstock.Uom")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,5 +23,6 @@ func ProjectflockRoutes(v1 fiber.Router, u user.UserService, s projectflock.Proj
|
|||||||
route.Get("/kandangs/lookup", ctrl.LookupProjectFlockKandang)
|
route.Get("/kandangs/lookup", ctrl.LookupProjectFlockKandang)
|
||||||
route.Post("/approvals", ctrl.Approval)
|
route.Post("/approvals", ctrl.Approval)
|
||||||
route.Get("/locations/:location_id/periods", ctrl.GetPeriodSummary)
|
route.Get("/locations/:location_id/periods", ctrl.GetPeriodSummary)
|
||||||
|
route.Put("/:id/resubmit", ctrl.Resubmit)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import (
|
|||||||
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
||||||
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||||
kandangRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
kandangRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
||||||
|
nonstockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/repositories"
|
||||||
warehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
warehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
||||||
|
projectBudgetRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
||||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
|
||||||
@@ -39,6 +41,7 @@ type ProjectflockService interface {
|
|||||||
GetPeriodSummary(ctx *fiber.Ctx, locationID uint) ([]KandangPeriodSummary, error)
|
GetPeriodSummary(ctx *fiber.Ctx, locationID uint) ([]KandangPeriodSummary, error)
|
||||||
GetProjectPeriods(ctx *fiber.Ctx, projectIDs []uint) (map[uint]int, error)
|
GetProjectPeriods(ctx *fiber.Ctx, projectIDs []uint) (map[uint]int, error)
|
||||||
Approval(ctx *fiber.Ctx, req *validation.Approve) ([]entity.ProjectFlock, error)
|
Approval(ctx *fiber.Ctx, req *validation.Approve) ([]entity.ProjectFlock, error)
|
||||||
|
Resubmit(ctx *fiber.Ctx, req *validation.Resubmit, id uint) (*entity.ProjectFlock, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type projectflockService struct {
|
type projectflockService struct {
|
||||||
@@ -47,8 +50,10 @@ type projectflockService struct {
|
|||||||
Repository repository.ProjectflockRepository
|
Repository repository.ProjectflockRepository
|
||||||
FlockRepo flockRepository.FlockRepository
|
FlockRepo flockRepository.FlockRepository
|
||||||
KandangRepo kandangRepository.KandangRepository
|
KandangRepo kandangRepository.KandangRepository
|
||||||
|
NonstockRepo nonstockRepository.NonstockRepository
|
||||||
WarehouseRepo warehouseRepository.WarehouseRepository
|
WarehouseRepo warehouseRepository.WarehouseRepository
|
||||||
ProductWarehouseRepo productWarehouseRepository.ProductWarehouseRepository
|
ProductWarehouseRepo productWarehouseRepository.ProductWarehouseRepository
|
||||||
|
ProjectBudgetRepo projectBudgetRepository.ProjectBudgetRepository
|
||||||
PivotRepo repository.ProjectFlockKandangRepository
|
PivotRepo repository.ProjectFlockKandangRepository
|
||||||
ApprovalSvc commonSvc.ApprovalService
|
ApprovalSvc commonSvc.ApprovalService
|
||||||
approvalWorkflow approvalutils.ApprovalWorkflowKey
|
approvalWorkflow approvalutils.ApprovalWorkflowKey
|
||||||
@@ -67,8 +72,11 @@ func NewProjectflockService(
|
|||||||
pivotRepo repository.ProjectFlockKandangRepository,
|
pivotRepo repository.ProjectFlockKandangRepository,
|
||||||
warehouseRepo warehouseRepository.WarehouseRepository,
|
warehouseRepo warehouseRepository.WarehouseRepository,
|
||||||
productWarehouseRepo productWarehouseRepository.ProductWarehouseRepository,
|
productWarehouseRepo productWarehouseRepository.ProductWarehouseRepository,
|
||||||
|
projectBudgetRepo projectBudgetRepository.ProjectBudgetRepository,
|
||||||
|
nonstockRepo nonstockRepository.NonstockRepository,
|
||||||
approvalSvc commonSvc.ApprovalService,
|
approvalSvc commonSvc.ApprovalService,
|
||||||
validate *validator.Validate,
|
validate *validator.Validate,
|
||||||
|
|
||||||
) ProjectflockService {
|
) ProjectflockService {
|
||||||
return &projectflockService{
|
return &projectflockService{
|
||||||
Log: utils.Log,
|
Log: utils.Log,
|
||||||
@@ -76,6 +84,7 @@ func NewProjectflockService(
|
|||||||
Repository: repo,
|
Repository: repo,
|
||||||
FlockRepo: flockRepo,
|
FlockRepo: flockRepo,
|
||||||
KandangRepo: kandangRepo,
|
KandangRepo: kandangRepo,
|
||||||
|
NonstockRepo: nonstockRepo,
|
||||||
WarehouseRepo: warehouseRepo,
|
WarehouseRepo: warehouseRepo,
|
||||||
ProductWarehouseRepo: productWarehouseRepo,
|
ProductWarehouseRepo: productWarehouseRepo,
|
||||||
PivotRepo: pivotRepo,
|
PivotRepo: pivotRepo,
|
||||||
@@ -289,7 +298,6 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||||
projectRepo := repository.NewProjectflockRepository(dbTransaction)
|
projectRepo := repository.NewProjectflockRepository(dbTransaction)
|
||||||
|
|
||||||
// Generate unique flock name (sequential per base name, starting from 1)
|
|
||||||
generatedName, _, err := s.generateSequentialFlockName(c.Context(), projectRepo, canonicalBase, 1, nil)
|
generatedName, _, err := s.generateSequentialFlockName(c.Context(), projectRepo, canonicalBase, 1, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -300,7 +308,6 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute period per kandang so every kandang maintains its own cycle history.
|
|
||||||
periods, err := projectRepo.GetNextPeriodsForKandangs(c.Context(), kandangIDs)
|
periods, err := projectRepo.GetNextPeriodsForKandangs(c.Context(), kandangIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -309,6 +316,10 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := s.UpsertProjectBudget(c.Context(), dbTransaction, createBody.Id, req.ProjectBudgets); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
action := entity.ApprovalActionCreated
|
action := entity.ApprovalActionCreated
|
||||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||||
_, err = approvalSvcTx.CreateApproval(
|
_, err = approvalSvcTx.CreateApproval(
|
||||||
@@ -1044,3 +1055,139 @@ func (s projectflockService) kandangRepoWithTx(tx *gorm.DB) kandangRepository.Ka
|
|||||||
}
|
}
|
||||||
return kandangRepository.NewKandangRepository(s.Repository.DB())
|
return kandangRepository.NewKandangRepository(s.Repository.DB())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s projectflockService) Resubmit(c *fiber.Ctx, req *validation.Resubmit, id uint) (*entity.ProjectFlock, error) {
|
||||||
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
existing, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations())
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock tidak ditemukan")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil data project flock")
|
||||||
|
}
|
||||||
|
|
||||||
|
kandangIDs := uniqueUintSlice(req.KandangIds)
|
||||||
|
kandangs, err := s.KandangRepo.GetByIDs(c.Context(), kandangIDs, nil)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Beberapa kandang tidak ditemukan")
|
||||||
|
}
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil data kandang")
|
||||||
|
}
|
||||||
|
if len(kandangs) != len(kandangIDs) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Beberapa kandang tidak ditemukan")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pb := range req.ProjectBudgets {
|
||||||
|
if err := commonSvc.EnsureRelations(c.Context(),
|
||||||
|
commonSvc.RelationCheck{Name: "Nonstock", ID: &pb.NonstockId, Exists: s.NonstockRepo.IdExists},
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||||
|
|
||||||
|
approvalSvc := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||||
|
|
||||||
|
var period int = 1
|
||||||
|
if len(existing.KandangHistory) > 0 {
|
||||||
|
period = existing.KandangHistory[0].Period
|
||||||
|
}
|
||||||
|
|
||||||
|
periods := make(map[uint]int, len(kandangIDs))
|
||||||
|
for _, kandangID := range kandangIDs {
|
||||||
|
periods[kandangID] = period
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.attachKandangs(c.Context(), dbTransaction, existing.Id, kandangIDs, periods); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.UpsertProjectBudget(c.Context(), dbTransaction, existing.Id, req.ProjectBudgets); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
action := entity.ApprovalActionUpdated
|
||||||
|
_, err = approvalSvc.CreateApproval(
|
||||||
|
c.Context(),
|
||||||
|
utils.ApprovalWorkflowProjectFlock,
|
||||||
|
existing.Id,
|
||||||
|
utils.ProjectFlockStepPengajuan,
|
||||||
|
&action,
|
||||||
|
actorID,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if fiberErr, ok := err.(*fiber.Error); ok {
|
||||||
|
return nil, fiberErr
|
||||||
|
}
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock tidak ditemukan")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengajukan ulang project flock")
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.getOneEntityOnly(c, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s projectflockService) UpsertProjectBudget(ctx context.Context, dbTransaction *gorm.DB, projectFlockID uint, budgets []validation.ProjectBudget) error {
|
||||||
|
|
||||||
|
if len(budgets) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
budgetRepo := projectBudgetRepository.NewProjectBudgetRepository(dbTransaction)
|
||||||
|
|
||||||
|
nonstockMap := make(map[uint]bool)
|
||||||
|
relationChecks := make([]commonSvc.RelationCheck, 0, len(budgets))
|
||||||
|
for _, b := range budgets {
|
||||||
|
if nonstockMap[b.NonstockId] {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Duplicate nonstock_id: %d", b.NonstockId))
|
||||||
|
}
|
||||||
|
nonstockMap[b.NonstockId] = true
|
||||||
|
nonstockID := b.NonstockId
|
||||||
|
relationChecks = append(relationChecks, commonSvc.RelationCheck{
|
||||||
|
Name: "Nonstock",
|
||||||
|
ID: &nonstockID,
|
||||||
|
Exists: s.NonstockRepo.IdExists,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := commonSvc.EnsureRelations(ctx, relationChecks...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := budgetRepo.DeleteMany(ctx, func(q *gorm.DB) *gorm.DB {
|
||||||
|
return q.Where("project_flock_id = ?", projectFlockID)
|
||||||
|
}); err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
records := make([]*entity.ProjectBudget, 0, len(budgets))
|
||||||
|
for _, b := range budgets {
|
||||||
|
records = append(records, &entity.ProjectBudget{
|
||||||
|
ProjectFlockId: projectFlockID,
|
||||||
|
NonstockId: b.NonstockId,
|
||||||
|
Price: b.Price,
|
||||||
|
Qty: b.Qty,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := budgetRepo.CreateMany(ctx, records, nil); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to save project budgets")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
type Create struct {
|
type Create struct {
|
||||||
FlockName string `json:"flock_name" validate:"required_strict"`
|
FlockName string `json:"flock_name" validate:"required_strict"`
|
||||||
AreaId uint `json:"area_id" validate:"required_strict,number,gt=0"`
|
AreaId uint `json:"area_id" validate:"required_strict,number,gt=0"`
|
||||||
Category string `json:"category" validate:"required_strict"`
|
Category string `json:"category" validate:"required_strict"`
|
||||||
FcrId uint `json:"fcr_id" validate:"required_strict,number,gt=0"`
|
FcrId uint `json:"fcr_id" validate:"required_strict,number,gt=0"`
|
||||||
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
||||||
KandangIds []uint `json:"kandang_ids" validate:"required,min=1,dive,gt=0"`
|
KandangIds []uint `json:"kandang_ids" validate:"required,min=1,dive,gt=0"`
|
||||||
|
ProjectBudgets []ProjectBudget `json:"project_budgets" validate:"required,min=1,dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Update struct {
|
type Update struct {
|
||||||
@@ -36,3 +37,14 @@ type Approve struct {
|
|||||||
ApprovableIds []uint `json:"approvable_ids" validate:"required_strict,min=1,dive,gt=0"`
|
ApprovableIds []uint `json:"approvable_ids" validate:"required_strict,min=1,dive,gt=0"`
|
||||||
Notes *string `json:"notes,omitempty" validate:"omitempty,max=500"`
|
Notes *string `json:"notes,omitempty" validate:"omitempty,max=500"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProjectBudget struct {
|
||||||
|
NonstockId uint `json:"nonstock_id" validate:"required_strict,number,gt=0"`
|
||||||
|
Price float64 `json:"price" validate:"required_strict,number,gt=0"`
|
||||||
|
Qty float64 `json:"qty" validate:"required_strict,number,gt=0"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Resubmit struct {
|
||||||
|
KandangIds []uint `json:"kandang_ids" validate:"required_strict,min=1,dive,gt=0"`
|
||||||
|
ProjectBudgets []ProjectBudget `json:"project_budgets" validate:"required_strict,min=1,dive"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -154,12 +154,14 @@ const (
|
|||||||
ApprovalWorkflowProjectFlock approvalutils.ApprovalWorkflowKey = approvalutils.ApprovalWorkflowKey("PROJECT_FLOCKS")
|
ApprovalWorkflowProjectFlock approvalutils.ApprovalWorkflowKey = approvalutils.ApprovalWorkflowKey("PROJECT_FLOCKS")
|
||||||
ProjectFlockStepPengajuan approvalutils.ApprovalStep = 1
|
ProjectFlockStepPengajuan approvalutils.ApprovalStep = 1
|
||||||
ProjectFlockStepAktif approvalutils.ApprovalStep = 2
|
ProjectFlockStepAktif approvalutils.ApprovalStep = 2
|
||||||
|
ProjectFlockStepSelesai approvalutils.ApprovalStep = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// projectFlockApprovalSteps keeps the workflow step definitions for project flock approvals.
|
// projectFlockApprovalSteps keeps the workflow step definitions for project flock approvals.
|
||||||
var ProjectFlockApprovalSteps = map[approvalutils.ApprovalStep]string{
|
var ProjectFlockApprovalSteps = map[approvalutils.ApprovalStep]string{
|
||||||
ProjectFlockStepPengajuan: "Pengajuan",
|
ProjectFlockStepPengajuan: "Pengajuan",
|
||||||
ProjectFlockStepAktif: "Aktif",
|
ProjectFlockStepAktif: "Aktif",
|
||||||
|
ProjectFlockStepSelesai: "Selesai",
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|||||||
@@ -263,7 +263,6 @@ func createProductWarehouseRow(t *testing.T, db *gorm.DB, qty float64) entity.Pr
|
|||||||
ProductId: 1,
|
ProductId: 1,
|
||||||
WarehouseId: 1,
|
WarehouseId: 1,
|
||||||
Quantity: qty,
|
Quantity: qty,
|
||||||
CreatedBy: 1,
|
|
||||||
}
|
}
|
||||||
if err := db.Create(&pw).Error; err != nil {
|
if err := db.Create(&pw).Error; err != nil {
|
||||||
t.Fatalf("create product warehouse: %v", err)
|
t.Fatalf("create product warehouse: %v", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user