|
@@ -27,16 +27,20 @@ import (
|
|
|
|
|
|
type Invoice struct {
|
|
|
*xweb.Action
|
|
|
- addinvoice xweb.Mapper `xweb:"/invoice/add"` //开发票
|
|
|
- showinvoice xweb.Mapper `xweb:"/invoice/show"` //查看发票
|
|
|
- callbackinvoice xweb.Mapper `xweb:"/invoice/callback"` //开发票回调
|
|
|
- newReplaceinvoice xweb.Mapper `xweb:"/invoice/replace"` //换发票
|
|
|
- refundinvoice xweb.Mapper `xweb:"/invoice/refund"` //退票
|
|
|
- invoiceinfo xweb.Mapper `xweb:"/invoice/info"` //订单详情数据
|
|
|
- available xweb.Mapper `xweb:"/invoice/available"` //是否可用开发票
|
|
|
- invoiceswitch xweb.Mapper `xweb:"/invoice/switch"` //发票开关
|
|
|
- invoiceQuery xweb.Mapper `xweb:"/invoice/query"` //发票信息查询
|
|
|
- invoiceSubmit xweb.Mapper `xweb:"/invoice/submit"` //发票信息提交
|
|
|
+ addinvoice xweb.Mapper `xweb:"/invoice/add"` //开发票
|
|
|
+ showinvoice xweb.Mapper `xweb:"/invoice/show"` //查看发票
|
|
|
+ newInvoiceShow xweb.Mapper `xweb:"/invoice/newShow"` //查看发票
|
|
|
+ showinvoiceList xweb.Mapper `xweb:"/invoice/showList"` //新查看发票 p537
|
|
|
+ callbackinvoice xweb.Mapper `xweb:"/invoice/callback"` //开发票回调
|
|
|
+ replaceinvoice xweb.Mapper `xweb:"/invoice/replace"` //换发票
|
|
|
+ newReplaceinvoice xweb.Mapper `xweb:"/invoice/newReplace"` //新换发票
|
|
|
+ refundinvoice xweb.Mapper `xweb:"/invoice/refund"` //退票
|
|
|
+ invoiceinfo xweb.Mapper `xweb:"/invoice/info"` //订单详情数据
|
|
|
+ available xweb.Mapper `xweb:"/invoice/available"` //是否可用开发票
|
|
|
+ invoiceswitch xweb.Mapper `xweb:"/invoice/switch"` //发票开关
|
|
|
+ invoiceQuery xweb.Mapper `xweb:"/invoice/query"` //发票信息查询
|
|
|
+ invoiceSubmit xweb.Mapper `xweb:"/invoice/submit"` //发票信息提交
|
|
|
+ getCompanyCode xweb.Mapper `xweb:"/invoice/getCompanyCode"` //开票联想税号
|
|
|
}
|
|
|
|
|
|
var dbname = "invoice"
|
|
@@ -181,6 +185,7 @@ func (this *Invoice) Invoiceswitch() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// Addinvoice 用户端-线上开票只能选电子普票
|
|
|
func (this *Invoice) Addinvoice() error {
|
|
|
defer qutil.Catch()
|
|
|
userId := qutil.ObjToString(this.GetSession("userId"))
|
|
@@ -202,18 +207,14 @@ func (this *Invoice) Addinvoice() error {
|
|
|
pos := qutil.IntAllDef(last, 0)
|
|
|
locks[pos].Lock()
|
|
|
defer locks[pos].Unlock()
|
|
|
- u := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": order_code, "user_id": userId, "applyBill_status": map[string]interface{}{"ne": 2}}, "order_money,product_type,order_channel,pay_way,pay_money,is_backstage_order,billingMode", "")
|
|
|
+ u := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": order_code, "user_id": userId, "applyBill_status": map[string]interface{}{"ne": 2}}, "order_money,product_type,pay_way,pay_money,is_backstage_order,billingMode,signing_subject,return_status,applybill_status", "")
|
|
|
if u != nil {
|
|
|
//后端代用户下单支持开票 order_channel = xdqd04
|
|
|
- if qutil.IntAll((*u)["billingMode"]) == 1 && (qutil.IntAll((*u)["is_backstage_order"]) != 1 || qutil.InterfaceToStr((*u)["order_channel"]) == "xdqd04") {
|
|
|
+ if qutil.IntAll((*u)["billingMode"]) == 1 && (qutil.IntAll((*u)["is_backstage_order"]) != 1 || (qutil.IntAll((*u)["is_backstage_order"]) == 1 && qutil.ObjToString((*u)["signing_subject"]) == "h01" && qutil.IntAll((*u)["return_status"]) == 1 && qutil.IntAll((*u)["applybill_status"]) == 0)) {
|
|
|
var prices float64
|
|
|
//公对公转账 账单金额可以修改 开发票应取实付金额 pay_money
|
|
|
//微信支付宝支付 pay_money为订单金额减去微信or支付包红包
|
|
|
- if qutil.ObjToString((*u)["pay_way"]) == "transferAccounts" {
|
|
|
- prices = qutil.Float64All((*u)["pay_money"]) / float64(100)
|
|
|
- } else {
|
|
|
- prices = qutil.Float64All((*u)["order_money"]) / float64(100)
|
|
|
- }
|
|
|
+ prices = qutil.Float64All((*u)["pay_money"]) / float64(100)
|
|
|
price = strconv.FormatFloat(prices, 'f', -1, 64)
|
|
|
product_name = (*u)["product_type"].(string)
|
|
|
applyBill_status = 1
|
|
@@ -449,24 +450,21 @@ func (this *Invoice) ShowinvoiceList() {
|
|
|
"ris": config.InvoiceConfig.Red_invoice_switch,
|
|
|
"rim": config.InvoiceConfig.Red_invoice_msg,
|
|
|
}
|
|
|
- invoices := util.Mysql.SelectBySql(fmt.Sprintf(`SELECT * FROM invoice WHERE order_code = '%s'`, order_code))
|
|
|
- if invoices != nil {
|
|
|
+ invoices := ShowList(order_code)
|
|
|
+ if invoices != nil && len(invoices) > 0 {
|
|
|
isIos := util.IsMobileIOS(this.Request.UserAgent())
|
|
|
var invoiceData []map[string]interface{}
|
|
|
- for _, data := range *invoices {
|
|
|
- delete(data, "user_id")
|
|
|
- var changed bool
|
|
|
- if data["only_Identifying"] != nil {
|
|
|
- //查询是否换票
|
|
|
- changed = util.Mysql.CountBySql(`SELECT count(*) FROM invoice WHERE order_code = '?' and invoice_status in (0,1) and only_Identifying = ?`, order_code, data["only_Identifying"]) > 1
|
|
|
+ for _, data := range invoices {
|
|
|
+ //是否换过票
|
|
|
+ isChanged := qutil.IntAll(data["isChanged"]) > 1
|
|
|
+ if isChanged && data["invoice_changed"] == 0 { //换过票的 只展示换票后的数据
|
|
|
+ continue
|
|
|
}
|
|
|
- //if changed && data["invoice_status"] == 0 { //此纪录为换票中的发票
|
|
|
- // continue
|
|
|
- //}
|
|
|
- data["changed"] = changed
|
|
|
- data["status"] = "processing"
|
|
|
+ delete(data, "user_id")
|
|
|
+ isJyInvoice := !strings.Contains(qutil.InterfaceToStr(data["url"]), "/jyInvoice/") //非数电票
|
|
|
+ isJyEntity := data["invoicing_entity"] != nil && qutil.InterfaceToStr(data["invoicing_entity"]) != config.Config.SigningSubject
|
|
|
+ data["changed"] = qutil.If(isJyInvoice || isChanged || isJyEntity, true, false)
|
|
|
if url := qutil.InterfaceToStr(data["url"]); url != "" {
|
|
|
- data["status"] = "success"
|
|
|
//ios 移动端
|
|
|
if isIos {
|
|
|
//国家税务局-增值税电子发票公共服务平台
|
|
@@ -475,9 +473,18 @@ func (this *Invoice) ShowinvoiceList() {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ var isReopen bool
|
|
|
+ if data["invoice_status"] == -1 {
|
|
|
+ isReopen = util.Mysql.Count("invoice_fail_record", map[string]interface{}{
|
|
|
+ "only_Identifying": data["only_Identifying"],
|
|
|
+ "order_code": order_code,
|
|
|
+ })+1 >= config.Config.SubmitNum
|
|
|
+ }
|
|
|
+ data["isReopen"] = isReopen
|
|
|
invoiceData = append(invoiceData, data)
|
|
|
}
|
|
|
this.ServeJson(map[string]interface{}{
|
|
|
+ "status": "success",
|
|
|
"invoiceData": invoiceData,
|
|
|
"redSwitchInfo": redSwitchInfo,
|
|
|
})
|
|
@@ -490,12 +497,39 @@ func (this *Invoice) ShowinvoiceList() {
|
|
|
}
|
|
|
|
|
|
this.ServeJson(map[string]interface{}{
|
|
|
+ "status": "fail",
|
|
|
"orderData": data,
|
|
|
"redSwitchInfo": redSwitchInfo,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func ShowList(order_code string) []map[string]interface{} {
|
|
|
+ data := util.Mysql.SelectBySql(fmt.Sprintf(`SELECT *,(
|
|
|
+ SELECT count(1) as count FROM invoice b WHERE b.order_code = a.order_code and b.only_Identifying is not null and b.only_Identifying = a.only_Identifying
|
|
|
+) as isChanged FROM invoice a WHERE order_code = '%s' and invoice_status != -2 and invoice_variety is not null and invoice_variety not LIKE '%s' ORDER BY create_time DESC`, order_code, "%纸质%"))
|
|
|
+ if data == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return *data
|
|
|
+}
|
|
|
+
|
|
|
+func (this *Invoice) NewInvoiceShow() {
|
|
|
+ stype := this.GetString("stype")
|
|
|
+ code := this.GetString("code")
|
|
|
+ data := make(map[string]interface{})
|
|
|
+ switch stype {
|
|
|
+ case "1": //订单回显金额
|
|
|
+ data["pay_money"] = ResidueMoney(code)
|
|
|
+ case "2": //发票信息回显
|
|
|
+ invoice := util.Mysql.FindOne("invoice", map[string]interface{}{"id": code}, "id,order_code,invoice_money,invoice_type,invoice_content,invoice_variety,company_name,phone,mail,taxpayer_identnum,invoice_money,invoice_order_money,company_address,bank_name,recipient,delivery_address,bank_account,company_phone", "")
|
|
|
+ data["invoice"] = invoice
|
|
|
+ }
|
|
|
+ this.ServeJson(map[string]interface{}{
|
|
|
+ "data": data,
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
// 开发票回调
|
|
|
func (this *Invoice) Callbackinvoice() {
|
|
|
isRed, _ := this.GetBool("isRed")
|
|
@@ -1070,16 +1104,17 @@ func (this *Invoice) NewReplaceinvoice() {
|
|
|
return
|
|
|
}
|
|
|
invoice_type := this.GetString("invoice_type")
|
|
|
- phone := this.GetString("phone_num")
|
|
|
- e_mail := this.GetString("email")
|
|
|
- company_name := this.GetString("company")
|
|
|
- id_num := strings.ToUpper(this.GetString("id_num")) //纳税人识别号
|
|
|
+ phone := this.GetString("phone")
|
|
|
+ e_mail := this.GetString("mail")
|
|
|
+ company_name := this.GetString("company_name")
|
|
|
+ id_num := strings.ToUpper(this.GetString("taxpayer_identnum")) //纳税人识别号
|
|
|
invoice_status := 0
|
|
|
- userId := qutil.ObjToString(this.GetSession("userId"))
|
|
|
+ //userId := qutil.ObjToString(this.GetSession("userId")) 支持扫描换票
|
|
|
//order_code := this.GetString("order_code")
|
|
|
sid := this.GetString("sid")
|
|
|
- oRes := util.Mysql.FindOne(dbname, map[string]interface{}{"id": sid, "user_id": userId, "invoie_changed": 0}, "", "") //仅线上开发票可换票
|
|
|
- if oRes != nil && len(*oRes) > 0 {
|
|
|
+ oRes := util.Mysql.FindOne(dbname, map[string]interface{}{"id": sid, "invoie_changed": 0}, "", "") //仅线上开发票可换票
|
|
|
+ if oRes != nil && len(*oRes) > 0 &&
|
|
|
+ ((*oRes)["invoicing_entity"] == nil || qutil.InterfaceToStr((*oRes)["invoicing_entity"]) == config.Config.SigningSubject) {
|
|
|
var (
|
|
|
qSql string
|
|
|
errCode []string
|
|
@@ -1088,39 +1123,51 @@ func (this *Invoice) NewReplaceinvoice() {
|
|
|
)
|
|
|
if qutil.IntAll((*oRes)["invoice_status"]) == -2 {
|
|
|
this.ServeJson(map[string]interface{}{
|
|
|
- "error_code": -1,
|
|
|
- "error_msg": "发票状态错误",
|
|
|
+ "invoice_status": -2,
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
- if invoice_order_code := qutil.InterfaceToStr((*oRes)["invoice_order_code"]); invoice_order_code == "" ||
|
|
|
- len(strings.Split(invoice_order_code, ",")) <= 1 {
|
|
|
- resArr = append(resArr, *oRes)
|
|
|
- } else { //多订单联合开票
|
|
|
- qSql = fmt.Sprintf(`SELECT * FROM invoice WHERE invoice_order_code = '%s'`, qutil.InterfaceToStr((*oRes)["invoice_order_code"]))
|
|
|
+ if invoice_order_code := qutil.InterfaceToStr((*oRes)["invoice_order_code"]); len(strings.Split(invoice_order_code, ",")) > 1 {
|
|
|
+ qSql = fmt.Sprintf(`SELECT * FROM invoice WHERE invoice_order_code = '%s' `, qutil.InterfaceToStr((*oRes)["invoice_order_code"]))
|
|
|
res1 := util.Mysql.SelectBySql(qSql)
|
|
|
if res1 != nil && len(*res1) > 0 {
|
|
|
resArr = *res1
|
|
|
}
|
|
|
+ } else { //多订单联合开票
|
|
|
+ resArr = append(resArr, *oRes)
|
|
|
}
|
|
|
var isMail bool
|
|
|
+ tm := time.Now()
|
|
|
for _, res := range resArr {
|
|
|
- newUuid := uuid.New()
|
|
|
if res["only_Identifying"] == nil { //无唯一id 允许换票一次 生成唯一id
|
|
|
+ newUuid := uuid.New()
|
|
|
res["only_Identifying"] = newUuid
|
|
|
util.Mysql.Update(dbname, map[string]interface{}{"id": res["id"]}, map[string]interface{}{"only_Identifying": newUuid})
|
|
|
+ } else if util.Mysql.Count(dbname, map[string]interface{}{
|
|
|
+ "order_code": res["order_code"],
|
|
|
+ "user_id": res["user_id"],
|
|
|
+ "only_Identifying": res["only_Identifying"],
|
|
|
+ }) > 1 {
|
|
|
+ continue
|
|
|
}
|
|
|
+ res["phone"] = this.GetString("phone")
|
|
|
+ res["mail"] = this.GetString("mail")
|
|
|
+ res["invoice_content"] = this.GetString("invoice_content")
|
|
|
+ res["company_phone"] = this.GetString("company_phone")
|
|
|
+ res["taxpayer_identnum"] = this.GetString("taxpayer_identnum")
|
|
|
+ res["operable_time"] = FormatDate(&tm, Date_Full_Layout)
|
|
|
+ res["remark"] = this.GetString("remark")
|
|
|
+ res["invoice_variety"] = this.GetString("invoice_variety")
|
|
|
+ res["bank_account"] = this.GetString("bank_account")
|
|
|
+ res["company_address"] = this.GetString("company_address")
|
|
|
+ res["bank_name"] = this.GetString("bank_name")
|
|
|
+ res["recipient"] = this.GetString("recipient")
|
|
|
+ res["delivery_address"] = this.GetString("delivery_address")
|
|
|
+ res["product_type"] = this.GetString("bank_name")
|
|
|
data := res
|
|
|
delete(data, "id")
|
|
|
switch IsEdit(res, phone, e_mail, id_num, company_name, invoice_type) {
|
|
|
case true:
|
|
|
- if util.Mysql.Count(dbname, map[string]interface{}{
|
|
|
- "order_code": res["order_code"],
|
|
|
- "user_id": userId,
|
|
|
- "only_Identifying": res["only_Identifying"],
|
|
|
- }) > 1 {
|
|
|
- continue
|
|
|
- }
|
|
|
var html string
|
|
|
if invoice_type == "个人" {
|
|
|
emailHtml := emailHtml_gr
|
|
@@ -1133,9 +1180,8 @@ func (this *Invoice) NewReplaceinvoice() {
|
|
|
}
|
|
|
data["invoice_changed"] = 1
|
|
|
data["invoice_status"] = 1
|
|
|
- data["billing_time"] = time.Now().Unix()
|
|
|
- data["create_time"] = time.Now().Unix()
|
|
|
- data["user_id"] = userId
|
|
|
+ data["billing_time"] = tm.Unix()
|
|
|
+ data["create_time"] = tm.Unix()
|
|
|
order_id := util.Mysql.Insert(dbname, data)
|
|
|
if order_id == -1 {
|
|
|
errCode = append(errCode, fmt.Sprintf("%s_%s", res["order_code"], res["invoice_order_code"]))
|
|
@@ -1147,7 +1193,7 @@ func (this *Invoice) NewReplaceinvoice() {
|
|
|
case false:
|
|
|
if util.Mysql.Count(dbname, map[string]interface{}{
|
|
|
"order_code": res["order_code"],
|
|
|
- "user_id": userId,
|
|
|
+ "user_id": res["user_id"],
|
|
|
"only_Identifying": res["only_Identifying"],
|
|
|
}) > 1 {
|
|
|
continue
|
|
@@ -1163,8 +1209,7 @@ func (this *Invoice) NewReplaceinvoice() {
|
|
|
dataexport_data["applybill_company"] = company_name
|
|
|
}
|
|
|
dataexport_data["user_mail"] = e_mail
|
|
|
- util.Mysql.Update("dataexport_order", map[string]interface{}{"order_code": res["order_code"], "user_id": userId}, dataexport_data)
|
|
|
-
|
|
|
+ util.Mysql.Update("dataexport_order", map[string]interface{}{"order_code": res["order_code"]}, dataexport_data)
|
|
|
data["mail"] = e_mail
|
|
|
data["phone"] = phone
|
|
|
data["invoice_type"] = invoice_type
|
|
@@ -1172,7 +1217,6 @@ func (this *Invoice) NewReplaceinvoice() {
|
|
|
data["taxpayer_identnum"] = id_num
|
|
|
data["invoice_changed"] = 1
|
|
|
data["create_time"] = time.Now().Unix()
|
|
|
- data["user_id"] = userId
|
|
|
data["invoice_status"] = invoice_status
|
|
|
order_id := util.Mysql.Insert(dbname, data)
|
|
|
if order_id == -1 {
|
|
@@ -1190,8 +1234,7 @@ func (this *Invoice) NewReplaceinvoice() {
|
|
|
} else {
|
|
|
if qutil.IntAll((*oRes)["invoice_status"]) < 0 {
|
|
|
this.ServeJson(map[string]interface{}{
|
|
|
- "error_code": -1,
|
|
|
- "error_msg": "发票状态错误",
|
|
|
+ "invoice_status": invoice_status,
|
|
|
})
|
|
|
return
|
|
|
}
|
|
@@ -1323,6 +1366,19 @@ func LastInvoiceSource(orderCode string) int64 {
|
|
|
}
|
|
|
return 0
|
|
|
}
|
|
|
+
|
|
|
+// 查询订单最后开票状态
|
|
|
+func QmxInvoice(res map[string]interface{}) bool {
|
|
|
+ if res["is_backstage_order"] == 1 && res["order_channel"] != "xdqd04" {
|
|
|
+ if res["return_status"] == 1 && util.Mysql.Count("invoice", map[string]interface{}{
|
|
|
+ "order_code": res["order_code"],
|
|
|
+ }) == 0 && res["signing_subject"] == config.Config.SigningSubject {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
func (this *Invoice) Available() {
|
|
|
u := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": this.GetString("order_code")}, "pay_time", "")
|
|
|
status := 0
|
|
@@ -1359,22 +1415,173 @@ func delReplaceInvoice(query map[string]interface{}) bool {
|
|
|
return util.Mysql.Delete(dbname, query)
|
|
|
}
|
|
|
|
|
|
-// 发票信息提交
|
|
|
+func InvoiceAmount(orderCode string) (invoicedMoney int64) {
|
|
|
+ invoicedInfo := util.Mysql.SelectBySql(fmt.Sprintf("SELECT invoice_order_money,only_Identifying FROM invoice WHERE order_code = '%s' and invoice_status>=0", orderCode))
|
|
|
+ if invoicedInfo != nil && len(*invoicedInfo) > 0 {
|
|
|
+ onlyMap := make(map[string]int64)
|
|
|
+ for _, m := range *invoicedInfo {
|
|
|
+ if m["only_Identifying"] != nil { //过滤换票过程中的数据
|
|
|
+ onlyMap[qutil.InterfaceToStr(m["only_Identifying"])] = qutil.Int64All(m["invoice_order_money"])
|
|
|
+ } else {
|
|
|
+ invoicedMoney += qutil.Int64All(m["invoice_order_money"])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(onlyMap) > 0 {
|
|
|
+ for _, i := range onlyMap {
|
|
|
+ invoicedMoney += i
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// InvoiceSubmit 发票信息提交
|
|
|
func (this *Invoice) InvoiceSubmit() {
|
|
|
+ if !R.CheckReqParam(this.ResponseWriter, this.Request, "invoice_variety", "invoiceContent", "invoice_type", "phone", "mail") {
|
|
|
+ this.ServeJson(NewResult("", errors.New("缺少参数")))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if this.GetString("invoice_type") == "单位" && !R.CheckReqParam(this.ResponseWriter, this.Request, "company_name", "taxpayer_identnum") {
|
|
|
+ this.ServeJson(NewResult("", errors.New("缺少参数")))
|
|
|
+ return
|
|
|
+ }
|
|
|
now := time.Now()
|
|
|
- onlyIdentifying := encrypt.SE.DecodeString(this.GetString("onlyIdentifying"))
|
|
|
- invoiceMoney := encrypt.SE.DecodeString(this.GetString("invoiceMoney"))
|
|
|
- operator := encrypt.SE.Decode4HexByCheck(this.GetString("operator"))
|
|
|
- if onlyIdentifying == "" || invoiceMoney == "" {
|
|
|
- this.ServeJson(NewResult("", errors.New("传入参数不正确")))
|
|
|
+ again, _ := this.GetInteger("again") //是否是失败重新开票 0 首次提交 1 再此提交
|
|
|
+ oldOnlyIdentifying := this.GetString("oldOnlyIdentifying") //最后一次失败的发票信息唯一标识
|
|
|
+ data := map[string]interface{}{
|
|
|
+ //"order_code": orderCode,
|
|
|
+ "company_name": this.GetString("company_name"),
|
|
|
+ "phone": this.GetString("phone"),
|
|
|
+ "mail": this.GetString("mail"),
|
|
|
+ "invoice_type": this.GetString("invoice_type"),
|
|
|
+ "invoice_content": this.GetString("invoiceContent"),
|
|
|
+ "invoice_status": 0,
|
|
|
+ "invoice_changed": 0,
|
|
|
+ //"invoice_order_code": orderCode,
|
|
|
+ "company_phone": this.GetString("company_phone"),
|
|
|
+ "taxpayer_identnum": this.GetString("taxpayer_identnum"),
|
|
|
+ "create_time": time.Now().Unix(),
|
|
|
+ //"user_id": userId,
|
|
|
+ "operable_time": FormatDate(&now, Date_Full_Layout),
|
|
|
+ //"invoice_money": payMoney,
|
|
|
+ //"invoice_order_money": payMoney,
|
|
|
+ "invoicing_entity": "北京剑鱼信息技术有限公司",
|
|
|
+ "remark": this.GetString("remark"),
|
|
|
+ "source": 0,
|
|
|
+ "invoice_variety": this.GetString("invoice_variety"),
|
|
|
+ "bank_account": this.GetString("bank_account"),
|
|
|
+ //"only_Identifying": onlyIdentifying,
|
|
|
+ "company_address": this.GetString("company_address"),
|
|
|
+ "bank_name": this.GetString("bank_name"),
|
|
|
+ "recipient": this.GetString("recipient"),
|
|
|
+ "delivery_address": this.GetString("delivery_address"),
|
|
|
+ //"product_type": qutil.ObjToString((*orderInfo)["product_type"]),
|
|
|
+ }
|
|
|
+ if again == 1 {
|
|
|
+ err := OpenInvoiceAgain(oldOnlyIdentifying, data)
|
|
|
+ if err != nil {
|
|
|
+ this.ServeJson(NewResult("", err))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.ServeJson(NewResult("保存信息成功", nil))
|
|
|
return
|
|
|
}
|
|
|
- data := util.Mysql.FindOne("invoice", map[string]interface{}{
|
|
|
+ source, _ := this.GetInteger("source")
|
|
|
+ switch source {
|
|
|
+ case 0: //用户端开票
|
|
|
+ userId := qutil.ObjToString(this.GetSession("userId"))
|
|
|
+ if userId == "" {
|
|
|
+ this.ServeJson(NewResult("", errors.New("userId为空")))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ orderCode := this.GetString("order_code")
|
|
|
+ err := JyOpenInvoice(orderCode, userId, data)
|
|
|
+ if err != nil {
|
|
|
+ this.ServeJson(NewResult("", err))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ case 1: //管理后台扫码开票
|
|
|
+ onlyIdentifying := encrypt.SE.DecodeString(this.GetString("onlyIdentifying"))
|
|
|
+ invoiceMoney := encrypt.SE.DecodeString(this.GetString("invoiceMoney"))
|
|
|
+ operator := encrypt.SE.Decode4HexByCheck(this.GetString("operator"))
|
|
|
+ if onlyIdentifying == "" || invoiceMoney == "" {
|
|
|
+ this.ServeJson(NewResult("", errors.New("传入参数不正确")))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err := AdminOpenInvoice(onlyIdentifying, invoiceMoney, operator, data)
|
|
|
+ if err != nil {
|
|
|
+ this.ServeJson(NewResult("", err))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.ServeJson(NewResult("保存信息成功", nil))
|
|
|
+}
|
|
|
+
|
|
|
+func OpenInvoiceAgain(oldOnlyIdentifying string, data map[string]interface{}) error {
|
|
|
+ if oldOnlyIdentifying == "" {
|
|
|
+ return errors.New("缺少关键参数")
|
|
|
+ }
|
|
|
+ ok := InvoiceFailRecord(oldOnlyIdentifying)
|
|
|
+ if !ok {
|
|
|
+ return errors.New("插入失败记录出错")
|
|
|
+ }
|
|
|
+ if util.Mysql.Count("invoice_fail_record", map[string]interface{}{"only_Identifying": oldOnlyIdentifying}) >= int64(config.Config.SubmitNum) {
|
|
|
+ return errors.New("提交次数已达上限")
|
|
|
+ }
|
|
|
+ if !util.Mysql.Update("invoice", map[string]interface{}{"only_Identifying": oldOnlyIdentifying}, data) {
|
|
|
+ return errors.New("再次开票更新发票信息出错")
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func JyOpenInvoice(orderCode, userId string, data map[string]interface{}) error {
|
|
|
+ onlyIdentifying := fmt.Sprintf("%s%s%s", "aa", time.Now().Format("150405"), qutil.GetRandom(4))
|
|
|
+ orderInfo := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": orderCode}, "product_type,user_mail,pay_money,create_time,signing_subject", "")
|
|
|
+ if orderInfo == nil {
|
|
|
+ return errors.New("订单不存在")
|
|
|
+ }
|
|
|
+ createTime, _ := time.ParseInLocation("2006-01-02 15:04:05", qutil.ObjToString((*orderInfo)["create_time"]), time.Local)
|
|
|
+ if createTime.Unix() < config.InvoiceConfig.Order_createtime {
|
|
|
+ return errors.New("2024年之前的订单不在开票")
|
|
|
+ }
|
|
|
+ if qutil.ObjToString((*orderInfo)["signing_subject"]) == "h02" {
|
|
|
+ return errors.New("签约主体为拓普")
|
|
|
+ }
|
|
|
+ invoicedMoney := InvoiceAmount(orderCode) //已开票金额
|
|
|
+ invoiceMoney := qutil.Int64All((*orderInfo)["pay_money"]) - invoicedMoney
|
|
|
+ data["order_code"] = orderCode
|
|
|
+ data["invoice_order_code"] = orderCode
|
|
|
+ data["only_Identifying"] = onlyIdentifying
|
|
|
+ data["invoice_money"] = invoiceMoney
|
|
|
+ data["invoice_order_money"] = invoiceMoney
|
|
|
+ data["product_type"] = qutil.ObjToString((*orderInfo)["product_type"])
|
|
|
+ data["user_id"] = userId
|
|
|
+ if !util.Mysql.ExecTx("用户端开发票", func(tx *sql.Tx) bool {
|
|
|
+ if util.Mysql.InsertByTx(tx, "invoice", data) <= 0 {
|
|
|
+ log.Println("插入invoice出错", orderCode)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if !util.Mysql.UpdateByTx(tx, "dataexport_order", map[string]interface{}{
|
|
|
+ "order_code": orderCode,
|
|
|
+ }, map[string]interface{}{
|
|
|
+ "applybill_status": 1,
|
|
|
+ }) {
|
|
|
+ log.Println("更新dataexport_order出错", orderCode)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }) {
|
|
|
+ return errors.New("用户端开票插入数据出错")
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func AdminOpenInvoice(onlyIdentifying, invoiceMoney, operator string, data map[string]interface{}) error {
|
|
|
+ oldData := util.Mysql.FindOne("invoice", map[string]interface{}{
|
|
|
"only_Identifying": onlyIdentifying,
|
|
|
}, "id", "")
|
|
|
- if data != nil {
|
|
|
- this.ServeJson(NewResult("", errors.New("该订单发票信息已经提交过申请")))
|
|
|
- return
|
|
|
+ if oldData != nil {
|
|
|
+ return errors.New("该订单发票信息已经提交过申请")
|
|
|
}
|
|
|
orderArr := []string{}
|
|
|
mailOrderArr := []string{}
|
|
@@ -1393,49 +1600,31 @@ func (this *Invoice) InvoiceSubmit() {
|
|
|
//提交时订单金额再做一次校验
|
|
|
for orderCode, money := range orderMap {
|
|
|
if ResidueMoney(orderCode) < qutil.Int64All(money) {
|
|
|
- this.ServeJson(NewResult("", errors.New("该订单发票信息已经提交过申请")))
|
|
|
- return
|
|
|
+ return errors.New("该订单发票信息已经提交过申请")
|
|
|
}
|
|
|
}
|
|
|
if !util.Mysql.ExecTx("发票信息保存", func(tx *sql.Tx) bool {
|
|
|
for orderCode, money := range orderMap {
|
|
|
- userId := GetUserId(orderCode)
|
|
|
- orderInfo := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": orderCode}, "product_type,user_mail", "")
|
|
|
+ orderInfo := util.Mysql.FindOne("dataexport_order", map[string]interface{}{"order_code": orderCode}, "product_type,user_mail,user_id,create_time", "")
|
|
|
productType := ""
|
|
|
if orderInfo != nil {
|
|
|
productType = qutil.InterfaceToStr((*orderInfo)["product_type"])
|
|
|
}
|
|
|
- data := map[string]interface{}{
|
|
|
- "order_code": orderCode,
|
|
|
- "company_name": this.GetString("company_name"),
|
|
|
- "phone": this.GetString("phone"),
|
|
|
- "mail": this.GetString("mail"),
|
|
|
- "invoice_type": this.GetString("invoice_type"),
|
|
|
- "invoice_content": "信息技术服务-技术服务费",
|
|
|
- "invoice_status": 0,
|
|
|
- "invoice_changed": 0,
|
|
|
- "invoice_order_code": strings.Join(orderArr, ","),
|
|
|
- "company_phone": this.GetString("company_phone"),
|
|
|
- "taxpayer_identnum": this.GetString("taxpayer_identnum"),
|
|
|
- "create_time": time.Now().Unix(),
|
|
|
- "user_id": userId,
|
|
|
- "operator": operator,
|
|
|
- "operable_time": FormatDate(&now, Date_Full_Layout),
|
|
|
- "invoice_money": Allmoney,
|
|
|
- "invoice_order_money": money,
|
|
|
- "invoicing_entity": "北京剑鱼信息技术有限公司",
|
|
|
- "remark": this.GetString("remark"),
|
|
|
- "source": 1,
|
|
|
- "invoice_variety": this.GetString("invoice_variety"),
|
|
|
- "bank_account": this.GetString("bank_account"),
|
|
|
- "only_Identifying": onlyIdentifying,
|
|
|
- "company_address": this.GetString("company_address"),
|
|
|
- "bank_name": this.GetString("bank_name"),
|
|
|
- "recipient": this.GetString("recipient"),
|
|
|
- "delivery_address": this.GetString("delivery_address"),
|
|
|
- "product_type": productType,
|
|
|
+ createTime, _ := time.ParseInLocation("2006-01-02 15:04:05", qutil.ObjToString((*orderInfo)["create_time"]), time.Local)
|
|
|
+ if createTime.Unix() < config.InvoiceConfig.Order_createtime {
|
|
|
+ log.Println("2024年之前的订单不在开票", orderCode)
|
|
|
+ return false
|
|
|
}
|
|
|
+ data["order_code"] = orderCode
|
|
|
+ data["invoice_order_code"] = strings.Join(orderArr, ",")
|
|
|
+ data["only_Identifying"] = onlyIdentifying
|
|
|
+ data["invoice_money"] = Allmoney
|
|
|
+ data["invoice_order_money"] = money
|
|
|
+ data["product_type"] = productType
|
|
|
+ data["user_id"] = qutil.ObjToString((*orderInfo)["user_id"])
|
|
|
+ data["operator"] = operator
|
|
|
if util.Mysql.Insert("invoice", data) <= 0 {
|
|
|
+ log.Println("扫码开票插入invoice表出错", orderCode)
|
|
|
return false
|
|
|
}
|
|
|
//订单发票状态改成已申请
|
|
@@ -1444,85 +1633,47 @@ func (this *Invoice) InvoiceSubmit() {
|
|
|
}, map[string]interface{}{
|
|
|
"applybill_status": 1,
|
|
|
}) {
|
|
|
+ log.Println("扫码开票更新dataexport_order表出错", orderCode)
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
- if this.GetString("invoice_variety") == "电子普通发票" && Allmoney < 1000000 {
|
|
|
- //走航天金税开票
|
|
|
- var orders = []map[string]interface{}{}
|
|
|
- var items = []map[string]interface{}{}
|
|
|
- prices := qutil.Float64All(Allmoney) / float64(100)
|
|
|
- price := strconv.FormatFloat(prices, 'f', -1, 64)
|
|
|
- item := map[string]interface{}{
|
|
|
- "name": "技术服务费",
|
|
|
- "code": config.InvoiceConfig.Code,
|
|
|
- "yhzcbs": config.InvoiceConfig.Tax_policy,
|
|
|
- "lineType": config.InvoiceConfig.Invoice_nature,
|
|
|
- "taxRate": config.InvoiceConfig.Tax_rate,
|
|
|
- "taxPrice": price,
|
|
|
- "totalAmount": price,
|
|
|
- "quantity": "1",
|
|
|
- }
|
|
|
- items = append(items, item)
|
|
|
- order := map[string]interface{}{
|
|
|
- "billNo": onlyIdentifying,
|
|
|
- "items": items,
|
|
|
- }
|
|
|
- orders = append(orders, order)
|
|
|
- body := map[string]interface{}{
|
|
|
- "Swno": onlyIdentifying,
|
|
|
- "custType": "03",
|
|
|
- "orders": orders,
|
|
|
- "custTaxNo": this.GetString("taxpayer_identnum"),
|
|
|
- "changed": "0",
|
|
|
- "phone": this.GetString("phone"),
|
|
|
- }
|
|
|
- if this.GetString("invoice_type") == "单位" {
|
|
|
- body["custName"] = this.GetString("company_name")
|
|
|
- } else {
|
|
|
- body["custName"] = "个人"
|
|
|
- }
|
|
|
- if config.InvoiceConfig.Third_party_switch {
|
|
|
- go htjs(body, orderArr, this.GetString("invoice_type"), this.GetString("company_name"), this.GetString("taxpayer_identnum"), this.GetString("mail"), this.GetString("phone"))
|
|
|
- }
|
|
|
- } else {
|
|
|
- //给王航发信息
|
|
|
- recipientStr := ""
|
|
|
- deliveryAddressStr := ""
|
|
|
- if this.GetString("invoice_variety") == "纸质普通发票" || this.GetString("invoice_variety") == "纸质专用发票" {
|
|
|
- recipientStr = fmt.Sprintf("<p class=\"item\">\n <span class=\"label\">收件人:</span>\n <span class=\"value\">%s</span>\n </p>", this.GetString("recipient"))
|
|
|
- deliveryAddressStr = fmt.Sprintf("<p class=\"item\">\n <span class=\"label\">收件地址:</span>\n <span class=\"value\">%s</span>\n </p>", this.GetString("delivery_address"))
|
|
|
- }
|
|
|
- prices := qutil.Float64All(Allmoney) / float64(100)
|
|
|
- price := strconv.FormatFloat(prices, 'f', -1, 64)
|
|
|
- html := fmt.Sprintf(email_format_new,
|
|
|
- FormatDate(&now, Date_Full_Layout),
|
|
|
- strings.Join(orderArr, ","),
|
|
|
- strings.Join(mailOrderArr, ","),
|
|
|
- price,
|
|
|
- this.GetString("invoice_variety"),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("invoice_type") == "", "--", this.GetString("invoice_type"))),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("company_name") == "", "--", this.GetString("company_name"))),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("taxpayer_identnum") == "", "--", this.GetString("taxpayer_identnum"))),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("company_address") == "", "--", this.GetString("company_address"))),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("company_phone") == "", "--", this.GetString("company_phone"))),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("bank_name") == "", "--", this.GetString("bank_name"))),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("bank_account") == "", "--", this.GetString("bank_account"))),
|
|
|
- qutil.InterfaceToStr(qutil.If(this.GetString("remark") == "", "--", this.GetString("remark"))),
|
|
|
- recipientStr,
|
|
|
- this.GetString("phone"),
|
|
|
- deliveryAddressStr,
|
|
|
- )
|
|
|
- for _, v := range strings.Split(config.Config.FinanceMail, ",") {
|
|
|
- go InvoiceSendMail(v, html, fmt.Sprintf("客户申请开具%s", this.GetString("invoice_variety")))
|
|
|
+ return true
|
|
|
+ }) {
|
|
|
+ return errors.New("发票信息保存失败")
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func InvoiceFailRecord(oldOnlyIdentifying string) bool {
|
|
|
+ //开票失败再次提交
|
|
|
+ invoiceData := util.Mysql.Find("invoice", map[string]interface{}{"only_Identifying": oldOnlyIdentifying, "invoice_status": -1}, "", "", -1, -1)
|
|
|
+ if invoiceData == nil && len(*invoiceData) <= 0 {
|
|
|
+ log.Println("未找到开票记录", oldOnlyIdentifying)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ //插入开票失败记录表
|
|
|
+ ok := util.Mysql.ExecTx("插入开票失败记录表", func(tx *sql.Tx) bool {
|
|
|
+ for _, val := range *invoiceData {
|
|
|
+ delete(val, "id")
|
|
|
+ if util.Mysql.InsertByTx(tx, "invoice_fail_record", val) <= 0 {
|
|
|
+ return false
|
|
|
}
|
|
|
}
|
|
|
return true
|
|
|
- }) {
|
|
|
- this.ServeJson(NewResult("", errors.New("发票信息保存失败")))
|
|
|
- return
|
|
|
+ })
|
|
|
+ return ok
|
|
|
+}
|
|
|
+
|
|
|
+func (this *Invoice) GetCompanyCode() {
|
|
|
+ code := ""
|
|
|
+ companyInfo := util.Mysql.FindOne("entniche_info", map[string]interface{}{"name": this.GetString("companyName")}, "code", "")
|
|
|
+ if companyInfo != nil && len(*companyInfo) > 0 {
|
|
|
+ code = qutil.ObjToString((*companyInfo)["code"])
|
|
|
}
|
|
|
- this.ServeJson(NewResult("保存信息成功", nil))
|
|
|
+ this.ServeJson(NewResult(map[string]interface{}{
|
|
|
+ "code": code,
|
|
|
+ }, nil))
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
// 发票信息查询
|
|
@@ -1543,7 +1694,7 @@ func (this *Invoice) InvoiceQuery() {
|
|
|
}
|
|
|
invoiceOne := util.Mysql.FindOne("invoice", map[string]interface{}{
|
|
|
"only_Identifying": onlyIdentifying,
|
|
|
- }, " bank_account, company_phone,company_name, phone, mail,company_phone, invoice_type, invoice_content, url, invoice_status, invoice_serialnum, taxpayer_identnum, operator, operable_time, invoicing_entity, remark, invoice_variety, logistics_code, company_address, bank_name, recipient, delivery_address", "")
|
|
|
+ }, "id,invoice_changed,order_code, bank_account, company_phone,company_name, phone, mail,company_phone, invoice_type, invoice_content, url, invoice_status, invoice_serialnum, taxpayer_identnum, operator, operable_time, invoicing_entity, remark, invoice_variety, logistics_code, company_address, bank_name, recipient, delivery_address", " create_time DESC")
|
|
|
companyName := ""
|
|
|
if invoiceOne == nil {
|
|
|
//查询公司名称
|
|
@@ -1552,6 +1703,22 @@ func (this *Invoice) InvoiceQuery() {
|
|
|
if orderArr != nil && len(*orderArr) > 0 {
|
|
|
companyName = qutil.ObjToString((*orderArr)[0]["company_name"])
|
|
|
}
|
|
|
+ } else {
|
|
|
+ switch qutil.IntAll((*invoiceOne)["invoice_status"]) {
|
|
|
+ case 1:
|
|
|
+ //是否换票
|
|
|
+ isJyInvoice := !strings.Contains(qutil.InterfaceToStr((*invoiceOne)["url"]), "/jyInvoice/") //非数电票
|
|
|
+ isChanged := util.Mysql.Count("invoice", map[string]interface{}{
|
|
|
+ "only_Identifying": onlyIdentifying,
|
|
|
+ "order_code": (*invoiceOne)["order_code"],
|
|
|
+ }) > 1
|
|
|
+ (*invoiceOne)["changed"] = qutil.If(isJyInvoice || isChanged, true, false)
|
|
|
+ case -1: //失败支持重新提交否
|
|
|
+ (*invoiceOne)["isReopen"] = util.Mysql.Count("invoice_fail_record", map[string]interface{}{
|
|
|
+ "only_Identifying": (*invoiceOne)["only_Identifying"],
|
|
|
+ "order_code": (*invoiceOne)["order_code"],
|
|
|
+ })+1 >= config.Config.SubmitNum
|
|
|
+ }
|
|
|
}
|
|
|
this.ServeJson(NewResult(map[string]interface{}{
|
|
|
"orderCodes": strings.Join(orderArr, ","),
|
|
@@ -1657,6 +1824,16 @@ func sendMail(invoiceType, orderCode, companyName, taxpayerIdentnum, mail, phone
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// 剩余金额
|
|
|
+func InvoicePrice(orderData map[string]interface{}) int64 {
|
|
|
+ residueMoney := int64(0)
|
|
|
+ if qutil.Int64All(orderData["applybill_status"]) == 2 {
|
|
|
+ return residueMoney
|
|
|
+ }
|
|
|
+
|
|
|
+ return qutil.Int64All(orderData["pay_money"]) - InvoiceAmount(qutil.InterfaceToStr(orderData["order_code"]))
|
|
|
+}
|
|
|
+
|
|
|
// 订单剩余金额查询
|
|
|
func ResidueMoney(orderCode string) int64 {
|
|
|
residueMoney := int64(0)
|
|
@@ -1665,26 +1842,25 @@ func ResidueMoney(orderCode string) int64 {
|
|
|
if len(*orderData) == 0 || orderData == nil {
|
|
|
return residueMoney
|
|
|
}
|
|
|
- if qutil.Int64All((*orderData)[0]["applybill_status"]) == 2 {
|
|
|
- return residueMoney
|
|
|
- }
|
|
|
+ return InvoicePrice((*orderData)[0])
|
|
|
+
|
|
|
//发票信息查询
|
|
|
- invoiceData := util.Mysql.SelectBySql("select invoice_status,sum(invoice_order_money) as money from invoice where order_code=? and invoice_status>=0 GROUP BY invoice_status", orderCode)
|
|
|
- if len(*orderData) == 0 || orderData == nil {
|
|
|
- } else {
|
|
|
- //开过几次票
|
|
|
- payMoney := qutil.Int64All((*orderData)[0]["pay_money"])
|
|
|
- allMoney := int64(0)
|
|
|
- for _, invoice := range *invoiceData {
|
|
|
- invoice_status := qutil.Int64All(invoice["invoice_status"])
|
|
|
- money := qutil.Int64All(invoice["money"])
|
|
|
- if invoice_status == 0 {
|
|
|
- return residueMoney
|
|
|
- } else {
|
|
|
- allMoney += money
|
|
|
- }
|
|
|
- }
|
|
|
- residueMoney = payMoney - allMoney
|
|
|
- }
|
|
|
- return residueMoney
|
|
|
+ //invoiceData := util.Mysql.SelectBySql("select invoice_status,sum(invoice_order_money) as money from invoice where order_code=? and invoice_status>=0 GROUP BY invoice_status", orderCode)
|
|
|
+ //if len(*orderData) == 0 || orderData == nil {
|
|
|
+ //} else {
|
|
|
+ // //开过几次票
|
|
|
+ // payMoney := qutil.Int64All((*orderData)[0]["pay_money"])
|
|
|
+ // allMoney := int64(0)
|
|
|
+ // for _, invoice := range *invoiceData {
|
|
|
+ // invoice_status := qutil.Int64All(invoice["invoice_status"])
|
|
|
+ // money := qutil.Int64All(invoice["money"])
|
|
|
+ // if invoice_status == 0 {
|
|
|
+ // return residueMoney
|
|
|
+ // } else {
|
|
|
+ // allMoney += money
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // residueMoney = payMoney - allMoney
|
|
|
+ //}
|
|
|
+ //return residueMoney
|
|
|
}
|