model/invoice.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
model/invoiceProduct.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
model/product.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
model/request/invoice.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
model/request/serviceContract.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
model/serviceContract.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
service/invoice.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
service/products.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
model/invoice.go
@@ -28,7 +28,7 @@ CourierNumber string `gorm:"courier_number" json:"courierNumber"` // 物流单号 CourierCompanyId int `gorm:"courier_company_id" json:"courierCompanyId"` // 物流公司 CourierCompany CourierCompany `gorm:"foreignKey:CourierCompanyId"` Products []Product `json:"products" gorm:"many2many:invoice_product;"` Products []*Product `json:"products" gorm:"many2many:invoice_product;"` } // InvoiceSearch 销售发票搜索条件 model/invoiceProduct.go
New file @@ -0,0 +1,131 @@ package model import ( "aps_crm/pkg/mysqlx" "gorm.io/gorm" ) type ( // InvoiceProduct 合同产品 InvoiceProduct struct { InvoiceId int `gorm:"invoice_id" json:"invoiceId"` ProductId int `gorm:"product_id" json:"productId"` } // InvoiceProductSearch 合同产品搜索条件 InvoiceProductSearch struct { InvoiceProduct Orm *gorm.DB Keyword string PageNum int PageSize int ProductIds []uint } ) func (InvoiceProduct) TableName() string { return "invoice_product" } func NewInvoiceProductSearch() *InvoiceProductSearch { return &InvoiceProductSearch{ Orm: mysqlx.GetDB(), } } func (slf *InvoiceProductSearch) build() *gorm.DB { var db = slf.Orm.Model(&InvoiceProduct{}) if len(slf.ProductIds) != 0 { db = db.Where("product_id in ?", slf.ProductIds) } if slf.InvoiceId != 0 { db = db.Where("invoice_id = ?", slf.InvoiceId) } return db } func (slf *InvoiceProductSearch) Create(record *InvoiceProduct) error { var db = slf.build() return db.Create(record).Error } func (slf *InvoiceProductSearch) CreateBatch(records []*InvoiceProduct) error { var db = slf.build() return db.Create(records).Error } func (slf *InvoiceProductSearch) Delete() error { var db = slf.build() return db.Delete(&InvoiceProduct{}).Error } func (slf *InvoiceProductSearch) Update(record *InvoiceProduct) error { var db = slf.build() return db.Updates(record).Error } func (slf *InvoiceProductSearch) FindAll() ([]*InvoiceProduct, error) { var db = slf.build() var record = make([]*InvoiceProduct, 0) err := db.Find(&record).Error return record, err } func (slf *InvoiceProductSearch) SetProductIds(ids []uint) *InvoiceProductSearch { slf.ProductIds = ids return slf } func (slf *InvoiceProductSearch) SetInvoiceId(id int) *InvoiceProductSearch { slf.InvoiceId = id return slf } func (slf *InvoiceProductSearch) SetOrm(tx *gorm.DB) *InvoiceProductSearch { slf.Orm = tx return slf } func (slf *InvoiceProductSearch) First() (*InvoiceProduct, error) { var db = slf.build() var record = new(InvoiceProduct) err := db.First(record).Error return record, err } func (slf *InvoiceProductSearch) Updates(values interface{}) error { var db = slf.build() return db.Updates(values).Error } func (slf *InvoiceProductSearch) Find() ([]*InvoiceProduct, int64, error) { var db = slf.build() var records = make([]*InvoiceProduct, 0) var total int64 if err := db.Count(&total).Error; err != nil { return records, total, err } if slf.PageNum > 0 && slf.PageSize > 0 { db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize) } err := db.Find(&records).Error return records, total, err } // InitDefaultData 初始化数据 func (slf *InvoiceProductSearch) InitDefaultData() error { var ( db = slf.Orm.Table(slf.TableName()) total int64 = 0 ) if err := db.Count(&total).Error; err != nil { return err } if total != 0 { return nil } records := []*InvoiceProduct{} return slf.CreateBatch(records) } model/product.go
@@ -6,7 +6,7 @@ ) type Product struct { Id int `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"` Id uint `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"` Name string `json:"name" gorm:"column:name;type:varchar(255);comment:产品名称"` Price decimal.Decimal `json:"price" gorm:"column:price;type:decimal(10,2);comment:产品价格"` Number string `json:"number" gorm:"column:number;type:varchar(255);comment:产品编号"` model/request/invoice.go
@@ -22,7 +22,7 @@ } type UpdateInvoice struct { Id int `json:"id"` Id int `json:"id" binding:"required"` ClientId int `gorm:"client_id" json:"clientId"` // 客户id InvoiceTypeId int `gorm:"invoice_type_id" json:"invoiceTypeId"` // 发票类型id PrincipalId int `gorm:"principal_id" json:"principalId"` // 销售负责人id @@ -35,6 +35,7 @@ InvoiceDate int `gorm:"invoice_date" json:"invoiceDate"` // 开票日期 CourierNumber string `gorm:"courier_number" json:"courierNumber"` // 物流单号 CourierCompanyId int `gorm:"courier_company_id" json:"courierCompanyId"` // 物流公司 Products []model.Product `json:"products"` //发票对应产品,从相应源单里获取 } type GetInvoiceList struct { model/request/serviceContract.go
@@ -25,7 +25,7 @@ ServiceTimes int `json:"serviceTimes"` Terms string `json:"terms"` Remark string `json:"remark"` Products []model.Product `json:"products"` Products []*model.Product `json:"products"` } type UpdateServiceContract struct { model/serviceContract.go
@@ -36,7 +36,7 @@ AmountReceived decimal.Decimal `gorm:"amount_received" json:"amountReceived"` // 已收金额 AmountInvoiced decimal.Decimal `gorm:"amount_invoiced" json:"amountInvoiced"` // 已开票金额 AmountUnInvoiced decimal.Decimal `gorm:"-" json:"amountUnInvoiced"` // 未开票金额 Products []Product `json:"products" gorm:"many2many:service_contract_product;"` Products []*Product `json:"products" gorm:"many2many:service_contract_product;"` gorm.Model `json:"-"` } service/invoice.go
@@ -18,12 +18,13 @@ func (InvoiceService) AddInvoice(invoice *model.Invoice) int { if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { serviceContract, err := model.NewServiceContractSearch().SetId(invoice.SourceId).First() serviceContract, err := model.NewServiceContractSearch().SetId(invoice.SourceId).SetPreload(true).First() if err != nil { return ecode.DBErr } var amountInvoiced decimal.Decimal for _, product := range invoice.Products { rightProducts := NewProductsService().PickRightProducts(invoice.Products, serviceContract.Products) for _, product := range rightProducts { amountInvoiced = serviceContract.AmountInvoiced.Add(product.Amount.Mul(product.Price)) } amountInvoiced = amountInvoiced.Round(2) @@ -35,13 +36,9 @@ if err != nil { return err } err = model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{ return model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{ "amount_invoiced": amountInvoiced, }) if err != nil { return err } return nil }) if err != nil { return ecode.DBErr @@ -86,9 +83,43 @@ } func (InvoiceService) UpdateInvoice(invoice *model.Invoice) int { err := model.NewInvoiceSearch().SetId(invoice.Id).Save(invoice) if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { serviceContract, err := model.NewServiceContractSearch().SetId(invoice.SourceId).SetPreload(true).First() if err != nil { return ecode.DBErr } var amountInvoiced decimal.Decimal newProducts, removedProducts := NewProductsService().PickDiffProducts(invoice.Products, serviceContract.Products) for _, product := range newProducts { amountInvoiced = serviceContract.AmountInvoiced.Add(product.Amount.Mul(product.Price)) } removedProductIds := make([]uint, 0, len(removedProducts)) for _, product := range removedProducts { amountInvoiced = serviceContract.AmountInvoiced.Sub(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 { return err } if len(removedProductIds) > 0 { err = model.NewInvoiceProductSearch().SetInvoiceId(invoice.Id).SetProductIds(removedProductIds).Delete() if err != nil { return err } } return model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{ "amount_invoiced": amountInvoiced, }) }) if err != nil { return ecode.DBErr } } return ecode.OK } service/products.go
New file @@ -0,0 +1,50 @@ package service import ( "aps_crm/model" ) type ProductsService struct{} func NewProductsService() ProductsService { return ProductsService{} } func (slf ProductsService) PickRightProducts(products, sourceProducts []*model.Product) (rightProducts []*model.Product) { productIdMap, productNumberMap := slf.getMappedProducts(sourceProducts) for _, product := range products { if p, ok := productIdMap[product.Id]; ok { rightProducts = append(rightProducts, p) } else if p, ok = productNumberMap[product.Number]; ok { rightProducts = append(rightProducts, p) } } return } func (slf ProductsService) PickDiffProducts(products, sourceProducts []*model.Product) (newProducts, removedProducts []*model.Product) { productIdMap, productNumberMap := slf.getMappedProducts(sourceProducts) productNumberMap2 := make(map[string]*model.Product, len(products)) for _, product := range products { if productIdMap[product.Id] == nil && productNumberMap[product.Number] == nil { newProducts = append(newProducts, product) } productNumberMap2[product.Number] = product } for productNumber, product := range productNumberMap { if productNumberMap2[productNumber] == nil { removedProducts = append(removedProducts, product) } } return } func (slf ProductsService) getMappedProducts(sourceProducts []*model.Product) (map[uint]*model.Product, map[string]*model.Product) { productIdMap := make(map[uint]*model.Product, len(sourceProducts)) productNumberMap := make(map[string]*model.Product, len(sourceProducts)) for _, product := range sourceProducts { productIdMap[product.Id] = product productNumberMap[product.Number] = product } return productIdMap, productNumberMap }