zhangqian
2023-08-11 7f589e6514eb4074d9a558bf4ff7efef3143b9db
新增,删除,和修改发票时修改销售明细未开票金额和已开票金额
6个文件已修改
169 ■■■■ 已修改文件
model/request/salesDetails.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/salesDetails.go 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/serviceContract.go 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/serviceOrderStatus.go 补丁 | 查看 | 原始文档 | blame | 历史
service/invoice.go 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/salesDetails.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/request/salesDetails.go
@@ -23,7 +23,7 @@
    Addressee           string          `json:"addressee" gorm:"column:addressee;type:varchar(255);comment:收件人"`
    Conditions          string          `json:"conditions" gorm:"column:conditions;type:text;comment:条件"`
    Remark              string          `json:"remark" gorm:"column:remark;type:text;comment:备注"`
    Products            []model.Product `json:"products" gorm:"many2many:sales_details_product;"`
    Products            []*model.Product `json:"products" gorm:"many2many:sales_details_product;"`
    LogisticCompany     string          `json:"logisticCompany" gorm:"column:logistic_company;type:varchar(255);comment:物流公司"`
    LogisticNumber      string          `json:"logisticNumber" gorm:"column:logistic_number;type:varchar(255);comment:物流单号"`
    LogisticCost        float64         `json:"logisticCost" gorm:"column:logistic_cost;type:decimal(10,2);comment:物流费用"`
model/salesDetails.go
@@ -28,14 +28,14 @@
        Addressee           string            `json:"addressee" gorm:"column:addressee;type:varchar(255);comment:收件人"`
        Conditions          string            `json:"conditions" gorm:"column:conditions;type:text;comment:条件"`
        Remark              string            `json:"remark" gorm:"column:remark;type:text;comment:备注"`
        Products            []Product         `json:"products" gorm:"many2many:sales_details_product;"`
        Products            []*Product        `json:"products" gorm:"many2many:sales_details_product;"`
        LogisticCompany     string            `json:"logisticCompany" gorm:"column:logistic_company;type:varchar(255);comment:物流公司"`
        LogisticNumber      string            `json:"logisticNumber" gorm:"column:logistic_number;type:varchar(255);comment:物流单号"`
        LogisticCost        float64           `json:"logisticCost" gorm:"column:logistic_cost;type:decimal(10,2);comment:物流费用"`
        AmountReceivable    decimal.Decimal   `gorm:"amount_receivable" json:"amountReceivable"` // 应收金额
        AmountReceived      decimal.Decimal   `gorm:"amount_received" json:"amountReceived"`     // 已收金额
        AmountInvoiced      decimal.Decimal   `gorm:"amount_invoiced" json:"amountInvoiced"`     // 已开票金额
        AmountUnInvoiced    decimal.Decimal   `gorm:"-" json:"amountUnInvoiced"`                 // 未开票金额
        AmountReceivable    decimal.Decimal   `gorm:"column:amount_receivable;type:decimal(12,2);comment:应收金额" json:"amountReceivable"`    // 应收金额
        AmountReceived      decimal.Decimal   `gorm:"column:amount_received;type:decimal(12,2);comment:已收金额" json:"amountReceived"`        // 已收金额
        AmountInvoiced      decimal.Decimal   `gorm:"column:amount_invoiced;type:decimal(12,2);comment:已开票金额" json:"amountInvoiced"`       // 已开票金额
        AmountUnInvoiced    decimal.Decimal   `gorm:"column:amount_not_invoiced;type:decimal(12,2);comment:未开票金额" json:"amountUnInvoiced"` // 未开票金额
        gorm.Model          `json:"-"`
    }
@@ -111,7 +111,7 @@
    return slf
}
func (slf *SalesDetailsSearch) Find() (*SalesDetails, error) {
func (slf *SalesDetailsSearch) First() (*SalesDetails, error) {
    var db = slf.build()
    var record = new(SalesDetails)
    err := db.First(record).Error
@@ -161,3 +161,15 @@
    slf.OrderBy = order
    return slf
}
func (slf *SalesDetailsSearch) UpdateByMap(upMap map[string]interface{}) error {
    var (
        db = slf.build()
    )
    if err := db.Updates(upMap).Error; err != nil {
        return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap)
    }
    return nil
}
model/serviceContract.go
@@ -34,9 +34,9 @@
        ServiceTimes            int                   `json:"serviceTimes" gorm:"column:service_times;type:int;comment:服务次数"`
        Terms                   string                `json:"terms" gorm:"column:terms;type:text;comment:条款"`
        Remark                  string                `json:"remark" gorm:"column:remark;type:text;comment:备注"`
        AmountReceivable        decimal.Decimal       `gorm:"column:amount_receivable;type:decimal(12,2);comment:未开票金额" json:"amountReceivable"`   // 应收金额
        AmountReceived          decimal.Decimal       `gorm:"column:amount_received;type:decimal(12,2);comment:未开票金额" json:"amountReceived"`       // 已收金额
        AmountInvoiced          decimal.Decimal       `gorm:"column:amount_invoiced;type:decimal(12,2);comment:未开票金额" json:"amountInvoiced"`       // 已开票金额
        AmountReceivable        decimal.Decimal       `gorm:"column:amount_receivable;type:decimal(12,2);comment:应收金额" json:"amountReceivable"`    // 应收金额
        AmountReceived          decimal.Decimal       `gorm:"column:amount_received;type:decimal(12,2);comment:已收金额" json:"amountReceived"`        // 已收金额
        AmountInvoiced          decimal.Decimal       `gorm:"column:amount_invoiced;type:decimal(12,2);comment:已开票金额" json:"amountInvoiced"`       // 已开票金额
        AmountUnInvoiced        decimal.Decimal       `gorm:"column:amount_not_invoiced;type:decimal(12,2);comment:未开票金额" json:"amountUnInvoiced"` // 未开票金额
        Products                []*Product            `json:"products" gorm:"many2many:service_contract_product;"`
        gorm.Model              `json:"-"`
model/serviceOrderStatus.go
service/invoice.go
@@ -17,7 +17,7 @@
func (InvoiceService) AddInvoice(invoice *model.Invoice) int {
    if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract {
    if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { //更新服务合同已开票金额
        serviceContract, err := model.NewServiceContractSearch().SetId(invoice.SourceId).SetPreload(true).First()
        if err != nil {
            return ecode.DBErr
@@ -30,9 +30,6 @@
        }
        amountInvoiced = amountInvoiced.Round(2)
        amountNotInvoiced = amountNotInvoiced.Round(2)
        //if amountInvoiced.GreaterThan(serviceContract.AmountReceivable) {
        //    return ecode.SContractInvoiceProductPriceGreaterThanReceivableAmountErr
        //}
        err = model.WithTransaction(func(db *gorm.DB) error {
            err = model.NewInvoiceSearch().Create(invoice)
            if err != nil {
@@ -46,13 +43,96 @@
        if err != nil {
            return ecode.DBErr
        }
    } else if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { //更新销售明细已开票金额
        salesDetails, err := model.NewSalesDetailsSearch().SetId(invoice.SourceId).SetPreload(true).First()
        if err != nil {
            return ecode.DBErr
        }
        var amountInvoiced, amountNotInvoiced decimal.Decimal
        rightProducts := NewProductsService().PickRightProducts(invoice.Products, salesDetails.Products)
        for _, product := range rightProducts {
            amountInvoiced = salesDetails.AmountInvoiced.Add(product.Amount.Mul(product.Price))
            amountNotInvoiced = salesDetails.AmountUnInvoiced.Sub(product.Amount.Mul(product.Price))
        }
        amountInvoiced = amountInvoiced.Round(2)
        amountNotInvoiced = amountNotInvoiced.Round(2)
        err = model.WithTransaction(func(db *gorm.DB) error {
            err = model.NewInvoiceSearch().Create(invoice)
            if err != nil {
                return err
            }
            return model.NewSalesDetailsSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{
                "amount_invoiced":     amountInvoiced,
                "amount_not_invoiced": amountNotInvoiced,
            })
        })
        if err != nil {
            return ecode.DBErr
        }
    }
    return ecode.OK
}
func (InvoiceService) DeleteInvoice(id int) int {
    invoice, err := model.NewInvoiceSearch().SetId(id).First()
    if err != nil {
        return ecode.DBErr
    }
    if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { //更新服务合同已开票金额
        serviceContract, err := model.NewServiceContractSearch().SetId(invoice.SourceId).SetPreload(true).First()
        if err != nil {
            return ecode.DBErr
        }
        var amountInvoiced, amountNotInvoiced decimal.Decimal
        rightProducts := NewProductsService().PickRightProducts(invoice.Products, serviceContract.Products)
        for _, product := range rightProducts {
            amountInvoiced = serviceContract.AmountInvoiced.Sub(product.Amount.Mul(product.Price))
            amountNotInvoiced = serviceContract.AmountUnInvoiced.Add(product.Amount.Mul(product.Price))
        }
        amountInvoiced = amountInvoiced.Round(2)
        amountNotInvoiced = amountNotInvoiced.Round(2)
        err = model.WithTransaction(func(db *gorm.DB) error {
    err := model.NewInvoiceSearch().SetId(id).Delete()
            if err != nil {
                return err
            }
            return model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{
                "amount_invoiced":     amountInvoiced,
                "amount_not_invoiced": amountNotInvoiced,
            })
        })
        if err != nil {
            return ecode.DBErr
        }
    } else if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { //更新销售明细已开票金额
        salesDetails, err := model.NewSalesDetailsSearch().SetId(invoice.SourceId).SetPreload(true).First()
        if err != nil {
            return ecode.DBErr
        }
        var amountInvoiced, amountNotInvoiced decimal.Decimal
        rightProducts := NewProductsService().PickRightProducts(invoice.Products, salesDetails.Products)
        for _, product := range rightProducts {
            amountInvoiced = salesDetails.AmountInvoiced.Sub(product.Amount.Mul(product.Price))
            amountNotInvoiced = salesDetails.AmountUnInvoiced.Add(product.Amount.Mul(product.Price))
        }
        amountInvoiced = amountInvoiced.Round(2)
        amountNotInvoiced = amountNotInvoiced.Round(2)
        err = model.WithTransaction(func(db *gorm.DB) error {
            err := model.NewInvoiceSearch().SetId(id).Delete()
            if err != nil {
                return err
            }
            return model.NewSalesDetailsSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{
                "amount_invoiced":     amountInvoiced,
                "amount_not_invoiced": amountNotInvoiced,
            })
        })
        if err != nil {
            return ecode.DBErr
        }
    }
    if err != nil {
        return ecode.DBErr
    }
@@ -91,20 +171,19 @@
        if err != nil {
            return ecode.DBErr
        }
        var amountInvoiced decimal.Decimal
        var amountInvoiced, amountNotInvoiced decimal.Decimal
        newProducts, removedProducts := NewProductsService().PickDiffProducts(invoice.Products, serviceContract.Products)
        for _, product := range newProducts {
            amountInvoiced = serviceContract.AmountInvoiced.Add(product.Amount.Mul(product.Price))
            amountNotInvoiced = serviceContract.AmountUnInvoiced.Sub(product.Amount.Mul(product.Price))
        }
        removedProductIds := make([]uint, 0, len(removedProducts))
        for _, product := range removedProducts {
            amountInvoiced = serviceContract.AmountInvoiced.Sub(product.Amount.Mul(product.Price))
            amountNotInvoiced = serviceContract.AmountUnInvoiced.Add(product.Amount.Mul(product.Price))
            removedProductIds = append(removedProductIds, product.Id)
        }
        amountInvoiced = amountInvoiced.Round(2)
        if amountInvoiced.GreaterThan(serviceContract.AmountReceivable) {
            return ecode.SContractInvoiceProductPriceGreaterThanReceivableAmountErr
        }
        err = model.WithTransaction(func(db *gorm.DB) error {
            err = model.NewInvoiceSearch().SetId(invoice.Id).Save(invoice)
            if err != nil {
@@ -118,6 +197,44 @@
            }
            return model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{
                "amount_invoiced": amountInvoiced,
                "amount_not_invoiced": amountNotInvoiced,
            })
        })
        if err != nil {
            return ecode.DBErr
        }
    } else if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { //更新销售明细已开票金额
        salesDetails, err := model.NewSalesDetailsSearch().SetId(invoice.SourceId).SetPreload(true).First()
        if err != nil {
            return ecode.DBErr
        }
        var amountInvoiced, amountNotInvoiced decimal.Decimal
        newProducts, removedProducts := NewProductsService().PickDiffProducts(invoice.Products, salesDetails.Products)
        for _, product := range newProducts {
            amountInvoiced = salesDetails.AmountInvoiced.Add(product.Amount.Mul(product.Price))
            amountNotInvoiced = salesDetails.AmountUnInvoiced.Sub(product.Amount.Mul(product.Price))
        }
        removedProductIds := make([]uint, 0, len(removedProducts))
        for _, product := range removedProducts {
            amountInvoiced = salesDetails.AmountInvoiced.Sub(product.Amount.Mul(product.Price))
            amountNotInvoiced = salesDetails.AmountUnInvoiced.Add(product.Amount.Mul(product.Price))
            removedProductIds = append(removedProductIds, product.Id)
        }
        amountInvoiced = amountInvoiced.Round(2)
        err = model.WithTransaction(func(db *gorm.DB) error {
            err = model.NewInvoiceSearch().SetId(invoice.Id).Save(invoice)
            if err != nil {
                return err
            }
            if len(removedProductIds) > 0 {
                err = model.NewInvoiceProductSearch().SetInvoiceId(invoice.Id).SetProductIds(removedProductIds).Delete()
                if err != nil {
                    return err
                }
            }
            return model.NewSalesDetailsSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{
                "amount_invoiced":     amountInvoiced,
                "amount_not_invoiced": amountNotInvoiced,
            })
        })
        if err != nil {
service/salesDetails.go
@@ -18,7 +18,7 @@
}
func (SalesDetailsService) DeleteSalesDetails(id int) int {
    _, err := model.NewSalesDetailsSearch().SetId(id).Find()
    _, err := model.NewSalesDetailsSearch().SetId(id).First()
    if err != nil {
        return ecode.SalesDetailsNotExist
    }
@@ -32,7 +32,7 @@
func (SalesDetailsService) UpdateSalesDetails(salesDetails *model.SalesDetails) int {
    // check salesDetails exist
    _, err := model.NewSalesDetailsSearch().SetId(salesDetails.Id).Find()
    _, err := model.NewSalesDetailsSearch().SetId(salesDetails.Id).First()
    if err != nil {
        return ecode.SalesDetailsNotExist
    }