新增和编辑服务合同时更新应收款金额,新增服务合同发票时更新已开票金额
| | |
| | | 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;"` |
| | | } |
| | | |
| | | // InvoiceSearch 销售发票搜索条件 |
| | |
| | | package model |
| | | |
| | | import "gorm.io/gorm" |
| | | import ( |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | | ) |
| | | |
| | | type Product struct { |
| | | Id int `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"` |
| | | Name string `json:"name" gorm:"column:name;type:varchar(255);comment:产品名称"` |
| | | Price float64 `json:"price" gorm:"column:price;type:decimal(10,2);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:产品编号"` |
| | | Amount int `json:"amount" gorm:"column:amount;type:int;comment:产品数量"` |
| | | Total float64 `json:"total" gorm:"column:total;type:decimal(10,2);comment:产品总价"` |
| | | Amount decimal.Decimal `json:"amount" gorm:"column:amount;type:int;comment:产品数量"` |
| | | Total decimal.Decimal `json:"total" gorm:"column:total;type:decimal(10,2);comment:产品总价"` |
| | | Desc string `json:"desc" gorm:"column:desc;type:varchar(255);comment:产品描述"` |
| | | gorm.Model `json:"-"` |
| | | } |
| | |
| | | |
| | | import ( |
| | | "aps_crm/constvar" |
| | | "aps_crm/model" |
| | | ) |
| | | |
| | | type AddInvoice struct { |
| | |
| | | InvoiceDate string `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 UpdateInvoice struct { |
| | |
| | | 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"` // 未开票金额 |
| | | Products []Product `json:"products" gorm:"many2many:service_contract_product;"` |
| | | gorm.Model `json:"-"` |
| | | } |
| | |
| | | } |
| | | switch slf.QueryClass { |
| | | case constvar.ServiceContractQueryClassExpireAfter30Day: |
| | | db = db.Where("end_time > ?", time.Now(), time.Now().AddDate(0, 0, 30)) |
| | | db = db.Where("end_time > ?", time.Now().AddDate(0, 0, 30).Format("2006-01-02")) |
| | | case constvar.ServiceContractQueryClassExpireAfter60Day: |
| | | db = db.Where("end_time > ?", time.Now(), time.Now().AddDate(0, 0, 60)) |
| | | db = db.Where("end_time > ?", time.Now().AddDate(0, 0, 60).Format("2006-01-02")) |
| | | case constvar.ServiceContractQueryClassExpiredBefore15Day: |
| | | db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -15)) |
| | | db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -15).Format("2006-01-02")) |
| | | case constvar.ServiceContractQueryClassExpiredBefore60Day: |
| | | db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -60)) |
| | | db = db.Where("end_time < ?", time.Now().AddDate(0, 0, -60).Format("2006-01-02")) |
| | | |
| | | } |
| | | switch slf.KeywordType { |
| | |
| | | SContractSetErr = 3300004 // 设置服务合同失败 |
| | | SContractUpdateErr = 3300005 // 更新服务合同失败 |
| | | SContractDeleteErr = 3300006 // 删除服务合同失败 |
| | | SContractProductPriceLowerThanInvoiceAmountErr = 3300007 //产品总价低于已开票金额 |
| | | SContractProductPriceLowerThanReceivedAmountErr = 3300008 //产品总价低于已收金额 |
| | | SContractInvoiceProductPriceGreaterThanReceivableAmountErr = 3300009 //开票总额高于应收金额 |
| | | |
| | | OrderManageExist = 3400001 // 订单管理已存在 |
| | | OrderManageNotExist = 3400002 // 订单管理不存在 |
| | |
| | | ChildrenExistErr: "存在子菜单", |
| | | MenuNotExist: "菜单不存在", |
| | | MenuNameExistErr: "菜单名已存在", |
| | | SContractProductPriceLowerThanInvoiceAmountErr: "产品总价低于已开票金额", |
| | | SContractProductPriceLowerThanReceivedAmountErr: "产品总价低于已收金额", |
| | | SContractInvoiceProductPriceGreaterThanReceivableAmountErr: "开票总额高于应收金额", |
| | | } |
| | | |
| | | func GetMsg(errCode int) (errMsg string) { |
| | |
| | | package service |
| | | |
| | | import ( |
| | | "aps_crm/constvar" |
| | | "aps_crm/model" |
| | | "aps_crm/model/request" |
| | | "aps_crm/pkg/ecode" |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | | ) |
| | | |
| | |
| | | |
| | | func (InvoiceService) AddInvoice(invoice *model.Invoice) int { |
| | | |
| | | err := model.WithTransaction(func(db *gorm.DB) error { |
| | | err := model.NewInvoiceSearch().Create(invoice) |
| | | if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { |
| | | serviceContract, err := model.NewServiceContractSearch().SetId(invoice.SourceId).First() |
| | | if err != nil { |
| | | return ecode.DBErr |
| | | } |
| | | var amountInvoiced decimal.Decimal |
| | | for _, product := range invoice.Products { |
| | | amountInvoiced = serviceContract.AmountInvoiced.Add(product.Amount.Mul(product.Price)) |
| | | } |
| | | amountInvoiced = amountInvoiced.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 { |
| | | return err |
| | | } |
| | | //if invoice.SourceType == constvar.InvoiceSourceTypeServiceContract { |
| | | // contract,err := model.NewServiceContractSearch().SetId(invoice.SourceId).First() |
| | | // if err != nil { |
| | | // return err |
| | | // } |
| | | // AmountInvoiced := contract.AmountReceived.Add() |
| | | // err := model.NewServiceContractSearch().SetId(invoice.SourceId).UpdateByMap(map[string]interface{}{ |
| | | // "amount_received" : |
| | | // }) |
| | | // if err != nil { |
| | | // return err |
| | | // } |
| | | //} |
| | | |
| | | err = 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 |
| | | } |
| | | } |
| | | |
| | | return ecode.OK |
| | | } |
| | |
| | | "aps_crm/constvar" |
| | | "aps_crm/model" |
| | | "aps_crm/pkg/ecode" |
| | | "github.com/shopspring/decimal" |
| | | ) |
| | | |
| | | type SContractService struct{} |
| | | |
| | | func (SContractService) AddServiceContract(serviceContract *model.ServiceContract) int { |
| | | serviceContract.AmountReceivable = decimal.Zero.Round(2) |
| | | serviceContract.AmountInvoiced = decimal.Zero.Round(2) |
| | | serviceContract.AmountReceived = decimal.Zero.Round(2) |
| | | for _, product := range serviceContract.Products { |
| | | serviceContract.AmountReceivable = serviceContract.AmountReceivable.Add(product.Amount.Mul(product.Price)) |
| | | } |
| | | serviceContract.AmountReceivable = serviceContract.AmountReceivable.Round(2) |
| | | err := model.NewServiceContractSearch().Create(serviceContract) |
| | | if err != nil { |
| | | return ecode.SContractExist |
| | |
| | | |
| | | func (SContractService) UpdateServiceContract(serviceContract *model.ServiceContract) int { |
| | | // check serviceContract exist |
| | | _, err := model.NewServiceContractSearch().SetId(serviceContract.Id).First() |
| | | old, err := model.NewServiceContractSearch().SetId(serviceContract.Id).First() |
| | | if err != nil { |
| | | return ecode.SContractNotExist |
| | | } |
| | | |
| | | var amountReceivable decimal.Decimal |
| | | for _, product := range serviceContract.Products { |
| | | amountReceivable = serviceContract.AmountReceivable.Add(product.Amount.Mul(product.Price)) |
| | | } |
| | | if amountReceivable.LessThan(serviceContract.AmountInvoiced) { |
| | | return ecode.SContractProductPriceLowerThanInvoiceAmountErr |
| | | } |
| | | if amountReceivable.LessThan(serviceContract.AmountReceived) { |
| | | return ecode.SContractProductPriceLowerThanReceivedAmountErr |
| | | } |
| | | serviceContract.AmountInvoiced = old.AmountReceived |
| | | serviceContract.AmountReceived = old.AmountReceived |
| | | serviceContract.AmountReceivable = amountReceivable.Round(2) |
| | | err = model.NewServiceContractSearch().SetId(serviceContract.Id).Update(serviceContract) |
| | | if err != nil { |
| | | return ecode.SContractSetErr |