336 lines
10 KiB
Go
Executable File
336 lines
10 KiB
Go
Executable File
package service
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/rovina/zsp-backend/internal/dto"
|
|
"github.com/rovina/zsp-backend/internal/model"
|
|
"github.com/rovina/zsp-backend/internal/repository"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ZSPFinancesService interface {
|
|
CreateFreightCharge(req *dto.ZSPFreightChargesCreateRequest) error
|
|
GetFreightCharge(id string) (*model.ZSPFreightCharges, error)
|
|
ListFreightCharges() ([]model.ZSPFreightCharges, error)
|
|
UpdateFreightCharge(id string, req *dto.ZSPFreightChargesUpdateRequest) error
|
|
DeleteFreightCharge(id string) error
|
|
|
|
CreateMiscCharge(req *dto.ZSPMiscChargesCreateRequest) error
|
|
GetMiscCharge(id string) (*model.ZSPMiscCharges, error)
|
|
ListMiscCharges() ([]model.ZSPMiscCharges, error)
|
|
UpdateMiscCharge(id string, req *dto.ZSPMiscChargesUpdateRequest) error
|
|
DeleteMiscCharge(id string) error
|
|
|
|
CreateServiceFee(req *dto.ZSPServiceFeesCreateRequest) error
|
|
GetServiceFee(id string) (*model.ZSPServiceFees, error)
|
|
ListServiceFees() ([]model.ZSPServiceFees, error)
|
|
UpdateServiceFee(id string, req *dto.ZSPServiceFeesUpdateRequest) error
|
|
DeleteServiceFee(id string) error
|
|
|
|
CreateCostBreakdown(req *dto.ZSPCostBreakdownCreateRequest) error
|
|
GetCostBreakdown(id string) (*model.ZSPCostBreakdown, error)
|
|
ListCostBreakdowns(businessID string) ([]model.ZSPCostBreakdown, error)
|
|
UpdateCostBreakdown(id string, req *dto.ZSPCostBreakdownUpdateRequest) error
|
|
DeleteCostBreakdown(id string) error
|
|
|
|
CreateProfitRecord(req *dto.ZSPProfitRecordCreateRequest) error
|
|
GetProfitRecord(id string) (*model.ZSPProfitRecord, error)
|
|
ListProfitRecords(filters map[string]string) ([]model.ZSPProfitRecord, error)
|
|
UpdateProfitRecord(id string, req *dto.ZSPProfitRecordUpdateRequest) error
|
|
DeleteProfitRecord(id string) error
|
|
}
|
|
|
|
type zspFinancesService struct {
|
|
repo repository.ZSPFinancesRepository
|
|
}
|
|
|
|
func NewZSPFinancesService(db *gorm.DB) ZSPFinancesService {
|
|
return &zspFinancesService{repo: repository.NewZSPFinancesRepository(db)}
|
|
}
|
|
|
|
// ============ 货代费用 ============
|
|
func (s *zspFinancesService) CreateFreightCharge(req *dto.ZSPFreightChargesCreateRequest) error {
|
|
currency := req.Currency
|
|
if currency == "" {
|
|
currency = "CNY"
|
|
}
|
|
charge := model.ZSPFreightCharges{
|
|
BillOfLading: req.BillOfLading,
|
|
ContractNumber: req.ContractNumber,
|
|
ExpenseItem: req.ExpenseItem,
|
|
Amount: req.Amount,
|
|
Currency: currency,
|
|
PaymentDate: parseDate(req.PaymentDate),
|
|
FreightCompanyName: req.FreightCompanyName,
|
|
Remark: req.Remark,
|
|
CreateTime: time.Now(),
|
|
UpdateTime: time.Now(),
|
|
}
|
|
return s.repo.CreateFreightCharge(&charge)
|
|
}
|
|
|
|
func (s *zspFinancesService) GetFreightCharge(id string) (*model.ZSPFreightCharges, error) {
|
|
return s.repo.GetFreightCharge(id)
|
|
}
|
|
|
|
func (s *zspFinancesService) ListFreightCharges() ([]model.ZSPFreightCharges, error) {
|
|
return s.repo.ListFreightCharges()
|
|
}
|
|
|
|
func (s *zspFinancesService) UpdateFreightCharge(id string, req *dto.ZSPFreightChargesUpdateRequest) error {
|
|
charge, err := s.repo.GetFreightCharge(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if req.BillOfLading != "" {
|
|
charge.BillOfLading = req.BillOfLading
|
|
}
|
|
if req.ContractNumber != "" {
|
|
charge.ContractNumber = req.ContractNumber
|
|
}
|
|
if req.ExpenseItem != "" {
|
|
charge.ExpenseItem = req.ExpenseItem
|
|
}
|
|
if req.Amount != 0 {
|
|
charge.Amount = req.Amount
|
|
}
|
|
if req.Currency != "" {
|
|
charge.Currency = req.Currency
|
|
}
|
|
if req.PaymentDate != "" {
|
|
charge.PaymentDate = parseDate(req.PaymentDate)
|
|
}
|
|
if req.FreightCompanyName != "" {
|
|
charge.FreightCompanyName = req.FreightCompanyName
|
|
}
|
|
charge.Remark = req.Remark
|
|
charge.UpdateTime = time.Now()
|
|
return s.repo.UpdateFreightCharge(charge)
|
|
}
|
|
|
|
func (s *zspFinancesService) DeleteFreightCharge(id string) error {
|
|
return s.repo.DeleteFreightCharge(id)
|
|
}
|
|
|
|
// ============ 杂费 ============
|
|
func (s *zspFinancesService) CreateMiscCharge(req *dto.ZSPMiscChargesCreateRequest) error {
|
|
currency := req.Currency
|
|
if currency == "" {
|
|
currency = "CNY"
|
|
}
|
|
charge := model.ZSPMiscCharges{
|
|
BillOfLading: req.BillOfLading,
|
|
ContractNumber: req.ContractNumber,
|
|
ExpenseItem: req.ExpenseItem,
|
|
Amount: req.Amount,
|
|
Currency: currency,
|
|
PaymentDate: parseDate(req.PaymentDate),
|
|
CompanyName: req.CompanyName,
|
|
Remark: req.Remark,
|
|
CreateTime: time.Now(),
|
|
UpdateTime: time.Now(),
|
|
}
|
|
return s.repo.CreateMiscCharge(&charge)
|
|
}
|
|
|
|
func (s *zspFinancesService) GetMiscCharge(id string) (*model.ZSPMiscCharges, error) {
|
|
return s.repo.GetMiscCharge(id)
|
|
}
|
|
|
|
func (s *zspFinancesService) ListMiscCharges() ([]model.ZSPMiscCharges, error) {
|
|
return s.repo.ListMiscCharges()
|
|
}
|
|
|
|
func (s *zspFinancesService) UpdateMiscCharge(id string, req *dto.ZSPMiscChargesUpdateRequest) error {
|
|
charge, err := s.repo.GetMiscCharge(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if req.BillOfLading != "" {
|
|
charge.BillOfLading = req.BillOfLading
|
|
}
|
|
if req.ContractNumber != "" {
|
|
charge.ContractNumber = req.ContractNumber
|
|
}
|
|
if req.ExpenseItem != "" {
|
|
charge.ExpenseItem = req.ExpenseItem
|
|
}
|
|
if req.Amount != 0 {
|
|
charge.Amount = req.Amount
|
|
}
|
|
if req.Currency != "" {
|
|
charge.Currency = req.Currency
|
|
}
|
|
if req.PaymentDate != "" {
|
|
charge.PaymentDate = parseDate(req.PaymentDate)
|
|
}
|
|
if req.CompanyName != "" {
|
|
charge.CompanyName = req.CompanyName
|
|
}
|
|
charge.Remark = req.Remark
|
|
charge.UpdateTime = time.Now()
|
|
return s.repo.UpdateMiscCharge(charge)
|
|
}
|
|
|
|
func (s *zspFinancesService) DeleteMiscCharge(id string) error {
|
|
return s.repo.DeleteMiscCharge(id)
|
|
}
|
|
|
|
// ============ 服务费 ============
|
|
func (s *zspFinancesService) CreateServiceFee(req *dto.ZSPServiceFeesCreateRequest) error {
|
|
currency := req.Currency
|
|
if currency == "" {
|
|
currency = "CNY"
|
|
}
|
|
fee := model.ZSPServiceFees{
|
|
BillOfLading: req.BillOfLading,
|
|
ContractNumber: req.ContractNumber,
|
|
Name: req.Name,
|
|
Amount: req.Amount,
|
|
Currency: currency,
|
|
Date: parseDate(req.Date),
|
|
Remark: req.Remark,
|
|
CreateTime: time.Now(),
|
|
UpdateTime: time.Now(),
|
|
}
|
|
return s.repo.CreateServiceFee(&fee)
|
|
}
|
|
|
|
func (s *zspFinancesService) GetServiceFee(id string) (*model.ZSPServiceFees, error) {
|
|
return s.repo.GetServiceFee(id)
|
|
}
|
|
|
|
func (s *zspFinancesService) ListServiceFees() ([]model.ZSPServiceFees, error) {
|
|
return s.repo.ListServiceFees()
|
|
}
|
|
|
|
func (s *zspFinancesService) UpdateServiceFee(id string, req *dto.ZSPServiceFeesUpdateRequest) error {
|
|
fee, err := s.repo.GetServiceFee(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if req.BillOfLading != "" {
|
|
fee.BillOfLading = req.BillOfLading
|
|
}
|
|
if req.ContractNumber != "" {
|
|
fee.ContractNumber = req.ContractNumber
|
|
}
|
|
if req.Name != "" {
|
|
fee.Name = req.Name
|
|
}
|
|
if req.Amount != 0 {
|
|
fee.Amount = req.Amount
|
|
}
|
|
if req.Currency != "" {
|
|
fee.Currency = req.Currency
|
|
}
|
|
if req.Date != "" {
|
|
fee.Date = parseDate(req.Date)
|
|
}
|
|
fee.Remark = req.Remark
|
|
fee.UpdateTime = time.Now()
|
|
return s.repo.UpdateServiceFee(fee)
|
|
}
|
|
|
|
func (s *zspFinancesService) DeleteServiceFee(id string) error {
|
|
return s.repo.DeleteServiceFee(id)
|
|
}
|
|
|
|
// ============ 成本构成 ============
|
|
func (s *zspFinancesService) CreateCostBreakdown(req *dto.ZSPCostBreakdownCreateRequest) error {
|
|
breakdown := model.ZSPCostBreakdown{
|
|
BusinessID: req.BusinessID,
|
|
BusinessType: req.BusinessType,
|
|
TotalCost: 0,
|
|
CreateTime: time.Now(),
|
|
UpdateTime: time.Now(),
|
|
}
|
|
return s.repo.CreateCostBreakdown(&breakdown)
|
|
}
|
|
|
|
func (s *zspFinancesService) GetCostBreakdown(id string) (*model.ZSPCostBreakdown, error) {
|
|
return s.repo.GetCostBreakdown(id)
|
|
}
|
|
|
|
func (s *zspFinancesService) ListCostBreakdowns(businessID string) ([]model.ZSPCostBreakdown, error) {
|
|
return s.repo.ListCostBreakdowns(businessID)
|
|
}
|
|
|
|
func (s *zspFinancesService) UpdateCostBreakdown(id string, req *dto.ZSPCostBreakdownUpdateRequest) error {
|
|
breakdown, err := s.repo.GetCostBreakdown(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
breakdown.FreightChargeTotal = req.FreightChargeTotal
|
|
breakdown.MiscChargeTotal = req.MiscChargeTotal
|
|
breakdown.ServiceFeeTotal = req.ServiceFeeTotal
|
|
breakdown.TotalCost = req.FreightChargeTotal + req.MiscChargeTotal + req.ServiceFeeTotal
|
|
breakdown.UpdateTime = time.Now()
|
|
return s.repo.UpdateCostBreakdown(breakdown)
|
|
}
|
|
|
|
func (s *zspFinancesService) DeleteCostBreakdown(id string) error {
|
|
return s.repo.DeleteCostBreakdown(id)
|
|
}
|
|
|
|
// ============ 利润记录 ============
|
|
func (s *zspFinancesService) CreateProfitRecord(req *dto.ZSPProfitRecordCreateRequest) error {
|
|
record := model.ZSPProfitRecord{
|
|
BusinessID: req.BusinessID,
|
|
BusinessType: req.BusinessType,
|
|
Revenue: req.Revenue,
|
|
TotalCost: req.TotalCost,
|
|
Profit: req.Revenue - req.TotalCost,
|
|
ProfitRate: calculateProfitRate(req.Revenue, req.TotalCost),
|
|
RecordDate: parseDate(req.RecordDate),
|
|
Remark: req.Remark,
|
|
CreateTime: time.Now(),
|
|
UpdateTime: time.Now(),
|
|
}
|
|
return s.repo.CreateProfitRecord(&record)
|
|
}
|
|
|
|
func (s *zspFinancesService) GetProfitRecord(id string) (*model.ZSPProfitRecord, error) {
|
|
return s.repo.GetProfitRecord(id)
|
|
}
|
|
|
|
func (s *zspFinancesService) ListProfitRecords(filters map[string]string) ([]model.ZSPProfitRecord, error) {
|
|
return s.repo.ListProfitRecords(filters)
|
|
}
|
|
|
|
func (s *zspFinancesService) UpdateProfitRecord(id string, req *dto.ZSPProfitRecordUpdateRequest) error {
|
|
record, err := s.repo.GetProfitRecord(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
record.Revenue = req.Revenue
|
|
record.TotalCost = req.TotalCost
|
|
record.Profit = req.Revenue - req.TotalCost
|
|
record.ProfitRate = calculateProfitRate(req.Revenue, req.TotalCost)
|
|
record.Remark = req.Remark
|
|
record.UpdateTime = time.Now()
|
|
return s.repo.UpdateProfitRecord(id, record)
|
|
}
|
|
|
|
func (s *zspFinancesService) DeleteProfitRecord(id string) error {
|
|
return s.repo.DeleteProfitRecord(id)
|
|
}
|
|
|
|
// ============ 辅助函数 ============
|
|
|
|
func parseDate(dateStr string) time.Time {
|
|
t, err := time.Parse("2006-01-02", dateStr)
|
|
if err != nil {
|
|
return time.Time{}
|
|
}
|
|
return t
|
|
}
|
|
|
|
func calculateProfitRate(revenue, totalCost float64) float64 {
|
|
if revenue == 0 {
|
|
return 0
|
|
}
|
|
return (revenue - totalCost) / revenue * 100
|
|
}
|