From 7f589e6514eb4074d9a558bf4ff7efef3143b9db Mon Sep 17 00:00:00 2001 From: zhangqian <zhangqian@123.com> Date: 星期五, 11 八月 2023 10:32:04 +0800 Subject: [PATCH] 新增,删除,和修改发票时修改销售明细未开票金额和已开票金额 --- model/serviceContract.go | 6 service/salesDetails.go | 4 model/salesDetails.go | 24 ++++- model/request/salesDetails.go | 34 ++++---- model/serviceOrderStatus.go | 14 +- service/invoice.go | 137 +++++++++++++++++++++++++++++++-- 6 files changed, 174 insertions(+), 45 deletions(-) diff --git a/model/request/salesDetails.go b/model/request/salesDetails.go index 1d12f61..7758bf6 100644 --- a/model/request/salesDetails.go +++ b/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:閿�鍞満浼歩d"` - 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:璐熻矗浜篿d"` - DeliveryDate string `json:"deliveryDate" gorm:"column:delivery_date;type:datetime;comment:浜よ揣鏃ユ湡"` - WechatOrderStatusId int `json:"wechatOrderStatusId" gorm:"column:wechat_order_status_id;type:int;comment:寰俊璁㈠崟鐘舵�乮d"` - 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:閿�鍞満浼歩d"` + 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:璐熻矗浜篿d"` + DeliveryDate string `json:"deliveryDate" gorm:"column:delivery_date;type:datetime;comment:浜よ揣鏃ユ湡"` + WechatOrderStatusId int `json:"wechatOrderStatusId" gorm:"column:wechat_order_status_id;type:int;comment:寰俊璁㈠崟鐘舵�乮d"` + 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 { diff --git a/model/salesDetails.go b/model/salesDetails.go index b318ab7..ff92423 100644 --- a/model/salesDetails.go +++ b/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 +} diff --git a/model/serviceContract.go b/model/serviceContract.go index 1d789f7..ccdb08f 100644 --- a/model/serviceContract.go +++ b/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:"-"` diff --git a/model/serviceOrderStatus.go b/model/serviceOrderStatus.go index b4b4046..4697fe2 100644 --- a/model/serviceOrderStatus.go +++ b/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 } ) diff --git a/service/invoice.go b/service/invoice.go index 203d8a8..d1500f1 100644 --- a/service/invoice.go +++ b/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 { diff --git a/service/salesDetails.go b/service/salesDetails.go index d504748..906fc2e 100644 --- a/service/salesDetails.go +++ b/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 } -- Gitblit v1.8.0