zhangqian
2023-08-11 7f589e6514eb4074d9a558bf4ff7efef3143b9db
新增,删除,和修改发票时修改销售明细未开票金额和已开票金额
6个文件已修改
219 ■■■■ 已修改文件
model/request/salesDetails.go 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/salesDetails.go 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/serviceContract.go 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/serviceOrderStatus.go 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/invoice.go 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/salesDetails.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/request/salesDetails.go
@@ -10,23 +10,23 @@
}
type SalesDetails struct {
    ClientId            int             `json:"clientId" gorm:"column:client_id;type:int;comment:客户id"`
    Number              string          `json:"number" gorm:"column:number;type:varchar(255);comment:销售子单号"`
    SaleChanceId        int             `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:销售机会id"`
    SaleType            int             `json:"saleType" gorm:"column:sale_type;type:int;comment:销售类型"`
    SignTime            string          `json:"signTime" gorm:"column:sign_time;type:datetime;comment:签单时间"`
    MemberId            int             `json:"memberId" gorm:"column:member_id;type:int;comment:负责人id"`
    DeliveryDate        string          `json:"deliveryDate" gorm:"column:delivery_date;type:datetime;comment:交货日期"`
    WechatOrderStatusId int             `json:"wechatOrderStatusId" gorm:"column:wechat_order_status_id;type:int;comment:微信订单状态id"`
    Address             string          `json:"address" gorm:"column:address;type:varchar(255);comment:地址"`
    Phone               string          `json:"phone" gorm:"column:phone;type:varchar(255);comment:电话"`
    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;"`
    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:物流费用"`
    ClientId            int              `json:"clientId" gorm:"column:client_id;type:int;comment:客户id"`
    Number              string           `json:"number" gorm:"column:number;type:varchar(255);comment:销售子单号"`
    SaleChanceId        int              `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:销售机会id"`
    SaleType            int              `json:"saleType" gorm:"column:sale_type;type:int;comment:销售类型"`
    SignTime            string           `json:"signTime" gorm:"column:sign_time;type:datetime;comment:签单时间"`
    MemberId            int              `json:"memberId" gorm:"column:member_id;type:int;comment:负责人id"`
    DeliveryDate        string           `json:"deliveryDate" gorm:"column:delivery_date;type:datetime;comment:交货日期"`
    WechatOrderStatusId int              `json:"wechatOrderStatusId" gorm:"column:wechat_order_status_id;type:int;comment:微信订单状态id"`
    Address             string           `json:"address" gorm:"column:address;type:varchar(255);comment:地址"`
    Phone               string           `json:"phone" gorm:"column:phone;type:varchar(255);comment:电话"`
    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;"`
    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:物流费用"`
}
type UpdateSalesDetails struct {
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
@@ -12,18 +12,18 @@
    // ServiceOrderStatus 服务单状态
    ServiceOrderStatus struct {
        Id   int    `json:"id" gorm:"column:id;type:int;primary_key;AUTO_INCREMENT"`
        Name string `json:"name" gorm:"column:name;type:varchar(255);not null;default:'';comment:名称"`
        Name string `json:"name" gorm:"column:name;type:varchar(255);not null;default:'';comment:名称"`
    }
    // ServiceOrderStatusSearch 服务单状态搜索条件
    ServiceOrderStatusSearch struct {
        ServiceOrderStatus
        Orm *gorm.DB
        QueryClass  constvar.ServiceOrderStatusQueryClass
        KeywordType constvar.ServiceOrderStatusKeywordType
        Keyword     string
        PageNum  int
        PageSize int
        Orm         *gorm.DB
        QueryClass  constvar.ServiceOrderStatusQueryClass
        KeywordType constvar.ServiceOrderStatusKeywordType
        Keyword     string
        PageNum     int
        PageSize    int
    }
)
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 {
    err := model.NewInvoiceSearch().SetId(id).Delete()
    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 {
@@ -117,7 +196,45 @@
                }
            }
            return model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{
                "amount_invoiced": amountInvoiced,
                "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
    }