feat(BE-229,234,235,230,231,232,233): purchase request and purchase order and fix master data dto

This commit is contained in:
ragilap
2025-11-17 09:39:30 +07:00
parent 8f74391f1e
commit 11f2389ec5
22 changed files with 2184 additions and 437 deletions
+123 -105
View File
@@ -4,129 +4,94 @@ import (
"time"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
areaDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto"
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/dto"
supplierDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/dto"
warehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/dto"
)
type SupplierBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
Alias string `json:"alias"`
Type string `json:"type"`
Category string `json:"category"`
}
type AreaBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
}
type LocationBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
}
type WarehouseBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
Area *AreaBaseDTO `json:"area,omitempty"`
Location *LocationBaseDTO `json:"location,omitempty"`
}
type ProductBaseDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
SKU *string `json:"sku,omitempty"`
}
type PurchaseItemDTO struct {
Id uint64 `json:"id"`
Product *ProductBaseDTO `json:"product,omitempty"`
Warehouse *WarehouseBaseDTO `json:"warehouse,omitempty"`
ProductWarehouseID *uint64 `json:"product_warehouse_id,omitempty"`
SubQty float64 `json:"sub_qty"`
TotalQty float64 `json:"total_qty"`
TotalUsed float64 `json:"total_used"`
Price float64 `json:"price"`
TotalPrice float64 `json:"total_price"`
type PurchaseListItemDTO struct {
Id uint64 `json:"id"`
PrNumber string `json:"pr_number"`
PoNumber *string `json:"po_number"`
Supplier *supplierDTO.SupplierBaseDTO `json:"supplier"`
CreditTerm *int `json:"credit_term"`
DueDate *time.Time `json:"due_date"`
PoDate *time.Time `json:"po_date"`
GrandTotal float64 `json:"grand_total"`
Notes *string `json:"notes"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Approval *approvalDTO.ApprovalBaseDTO `json:"approval"`
}
type PurchaseDetailDTO struct {
Id uint64 `json:"id"`
PrNumber string `json:"pr_number"`
Supplier *SupplierBaseDTO `json:"supplier,omitempty"`
CreditTerm *int `json:"credit_term,omitempty"`
DueDate *time.Time `json:"due_date,omitempty"`
GrandTotal float64 `json:"grand_total"`
Notes *string `json:"notes,omitempty"`
Items []PurchaseItemDTO `json:"items"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Id uint64 `json:"id"`
PrNumber string `json:"pr_number"`
PoNumber *string `json:"po_number"`
Supplier *supplierDTO.SupplierBaseDTO `json:"supplier"`
CreditTerm *int `json:"credit_term"`
DueDate *time.Time `json:"due_date"`
PoDate *time.Time `json:"po_date"`
GrandTotal float64 `json:"grand_total"`
Notes *string `json:"notes"`
Items []PurchaseItemDTO `json:"items"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Approval *approvalDTO.ApprovalBaseDTO `json:"approval"`
}
func toSupplierBaseDTO(s entity.Supplier) *SupplierBaseDTO {
if s.Id == 0 {
return nil
}
return &SupplierBaseDTO{
Id: s.Id,
Name: s.Name,
Alias: s.Alias,
Type: s.Type,
Category: s.Category,
}
}
func toWarehouseBaseDTO(w *entity.Warehouse) *WarehouseBaseDTO {
if w == nil || w.Id == 0 {
return nil
}
dto := &WarehouseBaseDTO{
Id: w.Id,
Name: w.Name,
}
if w.Area.Id != 0 {
dto.Area = &AreaBaseDTO{
Id: w.Area.Id,
Name: w.Area.Name,
}
}
if w.Location != nil && w.Location.Id != 0 {
dto.Location = &LocationBaseDTO{
Id: w.Location.Id,
Name: w.Location.Name,
}
}
return dto
}
func toProductBaseDTO(p *entity.Product) *ProductBaseDTO {
if p == nil || p.Id == 0 {
return nil
}
dto := &ProductBaseDTO{
Id: p.Id,
Name: p.Name,
}
if p.Sku != nil {
dto.SKU = p.Sku
}
return dto
type PurchaseItemDTO struct {
Id uint64 `json:"id"`
ProductID uint64 `json:"product_id"`
Product *productDTO.ProductBaseDTO `json:"product"`
WarehouseID uint64 `json:"warehouse_id"`
Warehouse *warehouseDTO.WarehouseBaseDTO `json:"warehouse"`
ProductWarehouseID *uint64 `json:"product_warehouse_id"`
SubQty float64 `json:"sub_qty"`
TotalQty float64 `json:"total_qty"`
TotalUsed float64 `json:"total_used"`
Price float64 `json:"price"`
TotalPrice float64 `json:"total_price"`
ReceivedDate *time.Time `json:"received_date"`
TravelNumber *string `json:"travel_number"`
TravelDocumentPath *string `json:"travel_document_path"`
VehicleNumber *string `json:"vehicle_number"`
}
func ToPurchaseItemDTO(item entity.PurchaseItem) PurchaseItemDTO {
dto := PurchaseItemDTO{
Id: item.Id,
ProductID: item.ProductId,
ProductWarehouseID: item.ProductWarehouseId,
WarehouseID: item.WarehouseId,
SubQty: item.SubQty,
TotalQty: item.TotalQty,
TotalUsed: item.TotalUsed,
Price: item.Price,
TotalPrice: item.TotalPrice,
ReceivedDate: item.ReceivedDate,
TravelNumber: item.TravelNumber,
TravelDocumentPath: item.TravelNumberDocs,
VehicleNumber: item.VehicleNumber,
}
if item.Product != nil {
dto.Product = toProductBaseDTO(item.Product)
if item.Product != nil && item.Product.Id != 0 {
summary := productDTO.ToProductBaseDTO(*item.Product)
dto.Product = &summary
}
if item.Warehouse != nil {
dto.Warehouse = toWarehouseBaseDTO(item.Warehouse)
if item.Warehouse != nil && item.Warehouse.Id != 0 {
summary := warehouseDTO.ToWarehouseBaseDTO(*item.Warehouse)
if item.Warehouse.Area.Id != 0 {
areaSummary := areaDTO.ToAreaBaseDTO(item.Warehouse.Area)
summary.Area = &areaSummary
}
if item.Warehouse.Location != nil && item.Warehouse.Location.Id != 0 {
locationSummary := locationDTO.ToLocationBaseDTO(*item.Warehouse.Location)
summary.Location = &locationSummary
}
dto.Warehouse = &summary
}
return dto
}
@@ -140,16 +105,69 @@ func ToPurchaseItemDTOs(items []entity.PurchaseItem) []PurchaseItemDTO {
}
func ToPurchaseDetailDTO(p entity.Purchase) PurchaseDetailDTO {
return PurchaseDetailDTO{
dto := PurchaseDetailDTO{
Id: p.Id,
PrNumber: p.PrNumber,
Supplier: toSupplierBaseDTO(p.Supplier),
PoNumber: p.PoNumber,
Supplier: mapSupplier(p.Supplier),
CreditTerm: p.CreditTerm,
DueDate: p.DueDate,
PoDate: p.PoDate,
GrandTotal: p.GrandTotal,
Notes: p.Notes,
Items: ToPurchaseItemDTOs(p.Items),
CreatedAt: p.CreatedAt,
UpdatedAt: p.UpdatedAt,
}
if approval := toPurchaseApprovalDTO(p); approval != nil {
dto.Approval = approval
}
return dto
}
func ToPurchaseListDTO(p entity.Purchase) PurchaseListItemDTO {
dto := PurchaseListItemDTO{
Id: p.Id,
PrNumber: p.PrNumber,
PoNumber: p.PoNumber,
Supplier: mapSupplier(p.Supplier),
CreditTerm: p.CreditTerm,
DueDate: p.DueDate,
PoDate: p.PoDate,
GrandTotal: p.GrandTotal,
Notes: p.Notes,
CreatedAt: p.CreatedAt,
UpdatedAt: p.UpdatedAt,
}
if approval := toPurchaseApprovalDTO(p); approval != nil {
dto.Approval = approval
}
return dto
}
func mapSupplier(s entity.Supplier) *supplierDTO.SupplierBaseDTO {
if s.Id == 0 {
return nil
}
summary := supplierDTO.ToSupplierBaseDTO(s)
return &summary
}
func ToPurchaseListDTOs(items []entity.Purchase) []PurchaseListItemDTO {
if len(items) == 0 {
return nil
}
result := make([]PurchaseListItemDTO, len(items))
for i, item := range items {
result[i] = ToPurchaseListDTO(item)
}
return result
}
func toPurchaseApprovalDTO(p entity.Purchase) *approvalDTO.ApprovalBaseDTO {
if p.LatestApproval == nil || p.LatestApproval.Id == 0 {
return nil
}
mapped := approvalDTO.ToApprovalDTO(*p.LatestApproval)
return &mapped
}