Merge remote-tracking branch 'origin/master'
New file |
| | |
| | | package model |
| | | |
| | | import ( |
| | | "aps_crm/pkg/mysqlx" |
| | | "fmt" |
| | | "gorm.io/gorm" |
| | | ) |
| | | |
| | | type ( |
| | | // SalesReturnProduct 服务合同和产品关联 |
| | | SalesReturnProduct struct { |
| | | SalesReturnId int `json:"id" gorm:"column:sales_details_id;type:int;primary_key;not null;default:0"` |
| | | ProductId uint `json:"name" gorm:"primary_key;column:product_id;type:int;not null;default:0;comment:产品id"` |
| | | } |
| | | |
| | | // SalesReturnProductSearch 销售明细和产品关联搜索条件 |
| | | SalesReturnProductSearch struct { |
| | | SalesReturnProduct |
| | | Orm *gorm.DB |
| | | Keyword string |
| | | PageNum int |
| | | PageSize int |
| | | } |
| | | ) |
| | | |
| | | func (SalesReturnProduct) TableName() string { |
| | | return "service_contract_product" |
| | | } |
| | | |
| | | func NewSalesReturnProductSearch() *SalesReturnProductSearch { |
| | | return &SalesReturnProductSearch{ |
| | | Orm: mysqlx.GetDB(), |
| | | } |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) build() *gorm.DB { |
| | | var db = slf.Orm.Model(&SalesReturnProduct{}) |
| | | |
| | | return db |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) Create(record *SalesReturnProduct) error { |
| | | var db = slf.build() |
| | | return db.Create(record).Error |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) CreateBatch(records []*SalesReturnProduct) error { |
| | | var db = slf.build() |
| | | return db.Create(records).Error |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) Delete() error { |
| | | var db = slf.build() |
| | | return db.Delete(&SalesReturnProduct{}).Error |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) Update(record *SalesReturnProduct) error { |
| | | var db = slf.build() |
| | | return db.Updates(record).Error |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) FindAll() ([]*SalesReturnProduct, error) { |
| | | var db = slf.build() |
| | | var record = make([]*SalesReturnProduct, 0) |
| | | err := db.Find(&record).Error |
| | | return record, err |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) SetPage(page, size int) *SalesReturnProductSearch { |
| | | slf.PageNum, slf.PageSize = page, size |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) SetOrm(tx *gorm.DB) *SalesReturnProductSearch { |
| | | slf.Orm = tx |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) First() (*SalesReturnProduct, error) { |
| | | var db = slf.build() |
| | | var record = new(SalesReturnProduct) |
| | | err := db.First(record).Error |
| | | return record, err |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) Updates(values interface{}) error { |
| | | var db = slf.build() |
| | | return db.Updates(values).Error |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) Save(record *SalesReturnProduct) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Save(record).Error; err != nil { |
| | | return fmt.Errorf("save err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalesReturnProductSearch) Find() ([]*SalesReturnProduct, int64, error) { |
| | | var db = slf.build() |
| | | var records = make([]*SalesReturnProduct, 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 *SalesReturnProductSearch) 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 := []*SalesReturnProduct{} |
| | | return slf.CreateBatch(records) |
| | | } |
| | |
| | | if slf.Name != "" { |
| | | db = db.Where("name = ?", slf.Name) |
| | | } |
| | | if len(slf.Ids) != 0 { |
| | | db = db.Where("id in ?", slf.Ids) |
| | | } |
| | | |
| | | return db |
| | | } |
New file |
| | |
| | | package model |
| | | |
| | | import ( |
| | | "aps_crm/pkg/mysqlx" |
| | | "fmt" |
| | | "gorm.io/gorm" |
| | | ) |
| | | |
| | | type ( |
| | | // ServiceContractProduct 服务合同和产品关联 |
| | | ServiceContractProduct struct { |
| | | ServiceContractId int `json:"id" gorm:"column:sales_details_id;type:int;primary_key;not null;default:0"` |
| | | ProductId uint `json:"name" gorm:"primary_key;column:product_id;type:int;not null;default:0;comment:产品id"` |
| | | } |
| | | |
| | | // ServiceContractProductSearch 销售明细和产品关联搜索条件 |
| | | ServiceContractProductSearch struct { |
| | | ServiceContractProduct |
| | | Orm *gorm.DB |
| | | Keyword string |
| | | PageNum int |
| | | PageSize int |
| | | } |
| | | ) |
| | | |
| | | func (ServiceContractProduct) TableName() string { |
| | | return "service_contract_product" |
| | | } |
| | | |
| | | func NewServiceContractProductSearch() *ServiceContractProductSearch { |
| | | return &ServiceContractProductSearch{ |
| | | Orm: mysqlx.GetDB(), |
| | | } |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) build() *gorm.DB { |
| | | var db = slf.Orm.Model(&ServiceContractProduct{}) |
| | | |
| | | return db |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) Create(record *ServiceContractProduct) error { |
| | | var db = slf.build() |
| | | return db.Create(record).Error |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) CreateBatch(records []*ServiceContractProduct) error { |
| | | var db = slf.build() |
| | | return db.Create(records).Error |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) Delete() error { |
| | | var db = slf.build() |
| | | return db.Delete(&ServiceContractProduct{}).Error |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) Update(record *ServiceContractProduct) error { |
| | | var db = slf.build() |
| | | return db.Updates(record).Error |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) FindAll() ([]*ServiceContractProduct, error) { |
| | | var db = slf.build() |
| | | var record = make([]*ServiceContractProduct, 0) |
| | | err := db.Find(&record).Error |
| | | return record, err |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) SetPage(page, size int) *ServiceContractProductSearch { |
| | | slf.PageNum, slf.PageSize = page, size |
| | | return slf |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) SetOrm(tx *gorm.DB) *ServiceContractProductSearch { |
| | | slf.Orm = tx |
| | | return slf |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) First() (*ServiceContractProduct, error) { |
| | | var db = slf.build() |
| | | var record = new(ServiceContractProduct) |
| | | err := db.First(record).Error |
| | | return record, err |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) Updates(values interface{}) error { |
| | | var db = slf.build() |
| | | return db.Updates(values).Error |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) Save(record *ServiceContractProduct) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Save(record).Error; err != nil { |
| | | return fmt.Errorf("save err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *ServiceContractProductSearch) Find() ([]*ServiceContractProduct, int64, error) { |
| | | var db = slf.build() |
| | | var records = make([]*ServiceContractProduct, 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 *ServiceContractProductSearch) 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 := []*ServiceContractProduct{} |
| | | return slf.CreateBatch(records) |
| | | } |
| | |
| | | Conditions string `json:"conditions" gorm:"column:conditions;type:text;comment:条件"` |
| | | CreatorId int `json:"creatorId" gorm:"column:creator_id;type:int;comment:创建人id"` |
| | | 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:SalesDetails_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 ( |
| | | // SalesDetailsProduct 销售明细和产品关联 |
| | | SalesDetailsProduct struct { |
| | | SalesDetailsId int `json:"id" gorm:"column:id;type:int;primary_key;AUTO_INCREMENT"` |
| | | ProductId uint `json:"name" gorm:"primary_key;column:name;type:varchar(255);not null;default:'';comment:名称"` |
| | | SalesDetailsId int `json:"id" gorm:"column:sales_details_id;type:int;primary_key;not null;default:0"` |
| | | ProductId uint `json:"name" gorm:"primary_key;column:product_id;type:int;not null;default:0;comment:产品id"` |
| | | } |
| | | |
| | | // SalesDetailsProductSearch 销售明细和产品关联搜索条件 |
| | |
| | | for _, product := range products { |
| | | if productIdMap[product.Id] == nil && productNumberMap[product.Number] == nil { |
| | | newProducts = append(newProducts, product) |
| | | } else if productIdMap[product.Id] != nil && slf.CheckProductChanged(productIdMap[product.Id], product) || productNumberMap[product.Number] != nil && slf.CheckProductChanged(productNumberMap[product.Number], product) { |
| | | removedProducts = append(removedProducts, product) |
| | | newProducts = append(newProducts, product) |
| | | } |
| | | productNumberMap2[product.Number] = product |
| | | } |
| | |
| | | return |
| | | } |
| | | |
| | | func (slf ProductsService) CheckProductChanged(originProduct, newProduct *model.Product) bool { |
| | | return originProduct.Number != newProduct.Number || |
| | | !originProduct.Amount.Equal(newProduct.Amount) || |
| | | !originProduct.Price.Equal(newProduct.Price) || |
| | | !originProduct.Total.Equal(newProduct.Total) |
| | | } |
| | | |
| | | 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)) |
| | |
| | | |
| | | func (SalesDetailsService) UpdateSalesDetails(salesDetails *model.SalesDetails) int { |
| | | // check salesDetails exist |
| | | old, err := model.NewSalesDetailsSearch().SetId(salesDetails.Id).First() |
| | | old, err := model.NewSalesDetailsSearch().SetId(salesDetails.Id).SetPreload(true).First() |
| | | if err != nil { |
| | | return ecode.SalesDetailsNotExist |
| | | } |
| | | var totalAmount decimal.Decimal |
| | | totalAmount = salesDetails.AmountTotal |
| | | newProducts, removedProducts := NewProductsService().PickDiffProducts(salesDetails.Products, old.Products) |
| | | for _, product := range newProducts { |
| | | for _, product := range salesDetails.Products { |
| | | totalAmount = totalAmount.Add(product.Amount.Mul(product.Price)) |
| | | } |
| | | removedProductIds := make([]uint, 0, len(removedProducts)) |
| | | for _, product := range removedProducts { |
| | | totalAmount = totalAmount.Sub(product.Amount.Mul(product.Price)) |
| | | removedProductIds = append(removedProductIds, product.Id) |
| | | } |
| | | salesDetails.AmountTotal = totalAmount.Round(2) |
| | | salesDetails.AmountReceivable = salesDetails.AmountTotal.Sub(salesDetails.AmountReceived) |
| | | salesDetails.AmountUnInvoiced = salesDetails.AmountTotal.Sub(salesDetails.AmountInvoiced) |
| | | |
| | | newProducts, removedProducts := NewProductsService().PickDiffProducts(salesDetails.Products, old.Products) |
| | | err = model.WithTransaction(func(db *gorm.DB) error { |
| | | err = model.NewSalesDetailsSearch().SetId(salesDetails.Id).Update(salesDetails) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | err = model.NewProductSearch(db).SetIds(removedProductIds).Delete() |
| | | if err != nil { |
| | | return err |
| | | if len(removedProducts) > 0 { |
| | | removedProductIds := make([]uint, 0, len(removedProducts)) |
| | | for _, product := range removedProducts { |
| | | totalAmount = totalAmount.Sub(product.Amount.Mul(product.Price)) |
| | | removedProductIds = append(removedProductIds, product.Id) |
| | | } |
| | | err = model.NewProductSearch(db).SetIds(removedProductIds).Delete() |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | err = model.NewProductSearch(db).CreateBatch(newProducts) |
| | | if err != nil { |
| | | return err |
| | | if len(newProducts) > 0 { |
| | | for _, p := range newProducts { |
| | | p.Id = 0 |
| | | } |
| | | err = model.NewProductSearch(db).CreateBatch(newProducts) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | var rel []*model.SalesDetailsProduct |
| | | for _, p := range newProducts { |
| | | rel = append(rel, &model.SalesDetailsProduct{ |
| | | SalesDetailsId: salesDetails.Id, |
| | | ProductId: p.Id, |
| | | }) |
| | | } |
| | | err = model.NewSalesDetailsProductSearch().CreateBatch(rel) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | var rel []*model.SalesDetailsProduct |
| | | for _, p := range newProducts { |
| | | rel = append(rel, &model.SalesDetailsProduct{ |
| | | SalesDetailsId: salesDetails.Id, |
| | | ProductId: p.Id, |
| | | }) |
| | | } |
| | | return model.NewSalesDetailsProductSearch().CreateBatch(rel) |
| | | return nil |
| | | |
| | | }) |
| | | |
| | | if err != nil { |
| | |
| | | } |
| | | salesReturn.AmountShouldRefund = salesReturn.AmountTotal |
| | | |
| | | err = model.NewSalesReturnSearch().SetId(salesReturn.Id).Update(salesReturn) |
| | | old, err := model.NewSalesReturnSearch().SetId(salesReturn.Id).SetPreload(true).First() |
| | | if err != nil { |
| | | return ecode.SalesReturnSetErr |
| | | return ecode.DBErr |
| | | } |
| | | newProducts, removedProducts := NewProductsService().PickDiffProducts(salesReturn.Products, old.Products) |
| | | err = model.WithTransaction(func(db *gorm.DB) error { |
| | | err := model.NewSalesReturnSearch().SetId(salesReturn.Id).Update(salesReturn) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | if len(removedProducts) > 0 { |
| | | removedProductIds := make([]uint, 0, len(removedProducts)) |
| | | for _, product := range removedProducts { |
| | | removedProductIds = append(removedProductIds, product.Id) |
| | | } |
| | | err = model.NewProductSearch(db).SetIds(removedProductIds).Delete() |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | if len(newProducts) > 0 { |
| | | for _, p := range newProducts { |
| | | p.Id = 0 |
| | | } |
| | | err = model.NewProductSearch(db).CreateBatch(newProducts) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | var rel []*model.SalesReturnProduct |
| | | for _, p := range newProducts { |
| | | rel = append(rel, &model.SalesReturnProduct{ |
| | | SalesReturnId: salesReturn.Id, |
| | | ProductId: p.Id, |
| | | }) |
| | | } |
| | | err = model.NewSalesReturnProductSearch().CreateBatch(rel) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | return nil |
| | | }) |
| | | |
| | | if err != nil { |
| | | return ecode.DBErr |
| | | } |
| | | |
| | | return ecode.OK |
| | |
| | | "aps_crm/model" |
| | | "aps_crm/pkg/ecode" |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | | ) |
| | | |
| | | type SContractService struct{} |
| | |
| | | |
| | | func (SContractService) UpdateServiceContract(serviceContract *model.ServiceContract) int { |
| | | // check serviceContract exist |
| | | old, err := model.NewServiceContractSearch().SetId(serviceContract.Id).First() |
| | | old, err := model.NewServiceContractSearch().SetId(serviceContract.Id).SetPreload(true).First() |
| | | if err != nil { |
| | | return ecode.SContractNotExist |
| | | } |
| | | var totalAmount decimal.Decimal |
| | | totalAmount = serviceContract.AmountTotal |
| | | newProducts, removedProducts := NewProductsService().PickDiffProducts(serviceContract.Products, old.Products) |
| | | for _, product := range newProducts { |
| | | for _, product := range serviceContract.Products { |
| | | totalAmount = totalAmount.Add(product.Amount.Mul(product.Price)) |
| | | } |
| | | removedProductIds := make([]uint, 0, len(removedProducts)) |
| | | for _, product := range removedProducts { |
| | | totalAmount = totalAmount.Sub(product.Amount.Mul(product.Price)) |
| | | removedProductIds = append(removedProductIds, product.Id) |
| | | } |
| | | serviceContract.AmountTotal = totalAmount.Round(2) |
| | | serviceContract.AmountReceivable = serviceContract.AmountTotal.Sub(serviceContract.AmountReceived) |
| | | serviceContract.AmountUnInvoiced = serviceContract.AmountTotal.Sub(serviceContract.AmountInvoiced) |
| | | err = model.WithTransaction(func(db *gorm.DB) error { |
| | | err := model.NewServiceContractSearch().Create(serviceContract) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | if len(removedProducts) > 0 { |
| | | removedProductIds := make([]uint, 0, len(removedProducts)) |
| | | for _, product := range removedProducts { |
| | | removedProductIds = append(removedProductIds, product.Id) |
| | | } |
| | | err = model.NewProductSearch(db).SetIds(removedProductIds).Delete() |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | if len(newProducts) > 0 { |
| | | for _, p := range newProducts { |
| | | p.Id = 0 |
| | | } |
| | | err = model.NewProductSearch(db).CreateBatch(newProducts) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | var rel []*model.ServiceContractProduct |
| | | for _, p := range newProducts { |
| | | rel = append(rel, &model.ServiceContractProduct{ |
| | | ServiceContractId: serviceContract.Id, |
| | | ProductId: p.Id, |
| | | }) |
| | | } |
| | | err = model.NewServiceContractProductSearch().CreateBatch(rel) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | return nil |
| | | }) |
| | | |
| | | err = model.NewServiceContractSearch().SetId(serviceContract.Id).Update(serviceContract) |
| | | if err != nil { |
| | | return ecode.SContractSetErr |
| | | return ecode.DBErr |
| | | } |
| | | |
| | | return ecode.OK |