runtime.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  1. package pkg2024
  2. import (
  3. "errors"
  4. "math"
  5. "strings"
  6. "zhiyuan/models/final"
  7. "zhiyuan/pkg/db"
  8. "zhiyuan/pkg/utils"
  9. "zhiyuan/services/form"
  10. "zhiyuan/services/material/bid"
  11. "zhiyuan/services/structs"
  12. )
  13. type ItemContext struct {
  14. Pkg *PkgForm
  15. ItemMap map[string]BuildItem
  16. //RegionMap map[int][]map[string]Region
  17. MatCache map[int64]final.FinalMat
  18. MatTypeCache map[int64]final.FinalMatType
  19. Space Space
  20. SpaceType int
  21. SpaceIndex int
  22. ItemNumber float64
  23. Item BuildItem
  24. Region Region
  25. oldRoomData RoomData
  26. }
  27. func (context *ItemContext) GetSpaceName() string {
  28. spaces := map[int]string{
  29. -1: "开工",
  30. 0: "卧室",
  31. 1: "客餐厅",
  32. 2: "厨房",
  33. 3: "卫生间",
  34. 4: "阳台",
  35. }
  36. spaceName := spaces[context.SpaceType]
  37. if context.SpaceType >= 0 {
  38. if context.Pkg.RoomData.Pkg.Layout[context.SpaceType] > 1 {
  39. spaceName += db.ToString(context.SpaceIndex + 1)
  40. }
  41. }
  42. return spaceName
  43. }
  44. type BuildBudgetItem struct {
  45. Type int `json:"type"`
  46. Name string `json:"name"`
  47. Unit string `json:"unit"`
  48. Number float64 `json:"number"`
  49. Price float64 `json:"price"`
  50. Total float64 `json:"total"`
  51. Remark string `json:"remark"`
  52. Index int `json:"index"`
  53. }
  54. type BuildBudgetCost struct {
  55. Direct float64 `json:"direct"`
  56. TransportProportion float64 `json:"transport_proportion"`
  57. Transport float64 `json:"transport"`
  58. SanitationProportion float64 `json:"sanitation_proportion"`
  59. Sanitation float64 `json:"sanitation"`
  60. ManageProportion float64 `json:"manage_proportion"`
  61. Manage float64 `json:"manage"`
  62. AdjustmentNumber float64 `json:"adjustment_number"`
  63. AdjustmentPrice float64 `json:"adjustment_price"`
  64. Adjustment float64 `json:"adjustment"`
  65. DesignNumber float64 `json:"design_number"`
  66. DesignPrice float64 `json:"design_price"`
  67. Design float64 `json:"design"`
  68. Total float64 `json:"total"`
  69. }
  70. type MaterialItem struct {
  71. Material int64 `json:"material"`
  72. Name string `json:"name"`
  73. Type string `json:"type"`
  74. Unit string `json:"unit"`
  75. Number float64 `json:"number"`
  76. Price float64 `json:"price"`
  77. Total float64 `json:"total"`
  78. CostNumber float64 `json:"cost_number"`
  79. CostTotal float64 `json:"cost_total"`
  80. Index int `json:"index"`
  81. }
  82. type DeductionData map[int][][]int
  83. type Contract struct {
  84. PkgPrice float64 `json:"pkg_price"`
  85. ToiletPrice []float64 `json:"toilet_price"`
  86. PkgTotal float64 `json:"pkg_total"`
  87. MaterialTotal float64 `json:"material_total"`
  88. PersonalBuildTotal float64 `json:"personal_build_total"`
  89. PersonalAmount float64 `json:"personal_amount"`
  90. PersonalTransportProportion float64 `json:"personal_transport_proportion"`
  91. PersonalTransport float64 `json:"personal_transport"`
  92. PersonalSanitationProportion float64 `json:"personal_sanitation_proportion"`
  93. PersonalSanitation float64 `json:"personal_sanitation"`
  94. PersonalManageProportion float64 `json:"personal_manage_proportion"`
  95. PersonalManage float64 `json:"personal_manage"`
  96. PersonalTotal float64 `json:"personal_total"`
  97. DesignPrice float64 `json:"design_price"`
  98. ChartPrice float64 `json:"chart_price"`
  99. //DesignTotal float64 `json:"design_total"`
  100. DirectTotal float64 `json:"direct_total"`
  101. DirectCost float64 `json:"direct_cost"`
  102. MaterialPurchaseTotal float64 `json:"material_purchase_total"`
  103. SpecialProjectTotal float64 `json:"special_project_total"`
  104. PurchaseTotal float64 `json:"purchase_total"`
  105. Cost float64 `json:"cost"`
  106. Taxes float64 `json:"taxes"`
  107. CostTotal float64 `json:"cost_total"`
  108. MaterialDeductionTotal float64 `json:"material_deduction_total"`
  109. BuildDeductionTotal float64 `json:"build_deduction_total"`
  110. }
  111. type BuildBudget struct {
  112. Items map[int][][]BuildBudgetItem `json:"items"`
  113. Cost BuildBudgetCost `json:"cost"`
  114. ControlAmount map[int]float64 `json:"control_amount"`
  115. Materials map[int][][]MaterialItem `json:"materials"`
  116. BuildAdditionalItems []PersonalItem `json:"build_additional_items"`
  117. MaterialAdditionalItems []PersonalItem `json:"material_additional_items"`
  118. BuildDeductionItems []PersonalItem `json:"build_deduction_items"`
  119. MaterialDeductionItems []PersonalItem `json:"material_deduction_items"`
  120. MaterialPurchaseItems []PersonalItem `json:"material_purchase_items"`
  121. BuildSpecialItems []PersonalItem `json:"build_special_items"`
  122. PersonalBuildItems []BuildBudgetItem `json:"personal_build_items"`
  123. PersonalBuildCost BuildBudgetCost `json:"personal_build_cost"`
  124. SpecialProjectItems []BuildBudgetItem `json:"special_project_items"`
  125. SpecialProjectTotal float64 `json:"special_project_total"`
  126. Contract Contract `json:"contract"`
  127. PackageAmount float64 `json:"package_amount"`
  128. SubsidyItems []SubsidyItem `json:"subsidy_items"`
  129. SubsidyTotal float64 `json:"subsidy_total"`
  130. SubsidyCollect float64 `json:"subsidy_collect"`
  131. MaterialCost float64 `json:"material_cost"`
  132. Profit float64 `json:"profit"`
  133. ProfitMargin float64 `json:"profit_margin"`
  134. }
  135. type BuildAdditionalItem struct {
  136. Item string `json:"item"`
  137. Number float64 `json:"number"`
  138. }
  139. type MaterialAdditionalItem struct {
  140. Material int64 `json:"material"`
  141. Number float64 `json:"number"`
  142. Purchase bool `json:"purchase"`
  143. }
  144. type SpecialProjectItem struct {
  145. Name string `json:"name"`
  146. Type int `json:"type"`
  147. Number float64 `json:"number"`
  148. Price float64 `json:"price"`
  149. Unit string `json:"unit"`
  150. Remark string `json:"remark"`
  151. }
  152. type AdditionalData struct {
  153. Builds []BuildAdditionalItem `json:"builds"`
  154. Materials []MaterialAdditionalItem `json:"materials"`
  155. Specials []SpecialProjectItem `json:"specials"`
  156. }
  157. type PersonalItem struct {
  158. Material int64 `json:"material"`
  159. Type int `json:"type"`
  160. Name string `json:"name"`
  161. Unit string `json:"unit"`
  162. Number float64 `json:"number"`
  163. Price float64 `json:"price"`
  164. Total float64 `json:"total"`
  165. Remark string `json:"remark"`
  166. SpaceType int `json:"space_type"`
  167. SpaceIndex int `json:"space_index"`
  168. Index int `json:"index"`
  169. Purchase bool `json:"purchase"`
  170. }
  171. type SubsidyItem struct {
  172. Name string `json:"name"`
  173. Unit string `json:"unit"`
  174. Number float64 `json:"number"`
  175. Price float64 `json:"price"`
  176. Total float64 `json:"total"`
  177. }
  178. func (from *PkgForm) NewContext() *ItemContext {
  179. context := new(ItemContext)
  180. context.Pkg = from
  181. context.ItemMap = make(map[string]BuildItem)
  182. for _, item := range BuildItems {
  183. context.ItemMap[item.Name] = item
  184. }
  185. context.MatCache = make(map[int64]final.FinalMat)
  186. matIds := make([]int64, 0)
  187. //context.RegionMap = make(map[int][]map[string]Region)
  188. for spaceType, spaceRegion := range from.RegionData {
  189. //context.RegionMap[spaceType] = make([]map[string]Region, 0)
  190. for _, regions := range spaceRegion {
  191. regionMap := make(map[string]Region)
  192. for regionIndex, region := range regions {
  193. regionMap[Regions[spaceType][regionIndex].Name] = region
  194. matIds = append(matIds, region.Material)
  195. }
  196. //context.RegionMap[spaceType] = append(context.RegionMap[spaceType], regionMap)
  197. }
  198. }
  199. mats := make([]final.FinalMat, 0)
  200. db.GetModel(map[string]interface{}{
  201. "id in": matIds,
  202. "deleted_at": 0,
  203. }, &mats)
  204. for _, mat := range mats {
  205. context.MatCache[mat.ID] = mat
  206. }
  207. if context.MatTypeCache == nil {
  208. context.MatTypeCache = make(map[int64]final.FinalMatType)
  209. types := make([]final.FinalMatType, 0)
  210. db.GetModel(map[string]interface{}{
  211. "deleted_at": 0,
  212. }, &types)
  213. for _, typ := range types {
  214. context.MatTypeCache[typ.ID] = typ
  215. }
  216. }
  217. return context
  218. }
  219. func (context *ItemContext) GetMat(id int64) *final.FinalMat {
  220. if context.MatCache == nil {
  221. context.MatCache = make(map[int64]final.FinalMat)
  222. }
  223. if _, ok := context.MatCache[id]; !ok {
  224. var mat final.FinalMat
  225. db.GetModel(map[string]interface{}{
  226. "id": id,
  227. "deleted_at": 0,
  228. }, &mat)
  229. if mat.ID != 0 {
  230. context.MatCache[id] = mat
  231. }
  232. }
  233. if mat, ok := context.MatCache[id]; ok {
  234. return &mat
  235. }
  236. return nil
  237. }
  238. func (context *ItemContext) GetMatTopType(id int64) *final.FinalMatType {
  239. for {
  240. if typ, ok := context.MatTypeCache[id]; ok {
  241. if typ.Pid != 0 {
  242. id = typ.Pid
  243. } else {
  244. break
  245. }
  246. } else {
  247. break
  248. }
  249. }
  250. if typ, ok := context.MatTypeCache[id]; ok {
  251. return &typ
  252. }
  253. return nil
  254. }
  255. func (from *PkgForm) Calc() error {
  256. context := from.NewContext()
  257. context.oldRoomData = from.RoomData
  258. return from.CalcInContext(context)
  259. }
  260. func (from *PkgForm) CalcInContext(context *ItemContext) error {
  261. from.RefreshRegion(context)
  262. err := CalcBuildBudget(context)
  263. if err != nil {
  264. return err
  265. }
  266. return nil
  267. }
  268. func CalcBuildBudget(context *ItemContext) error {
  269. context.Pkg.BuildBudget = BuildBudget{}
  270. context.Pkg.BuildBudget.ControlAmount = make(map[int]float64)
  271. context.Pkg.BuildBudget.Items = make(map[int][][]BuildBudgetItem)
  272. context.Pkg.BuildBudget.Materials = make(map[int][][]MaterialItem)
  273. context.Pkg.BuildBudget.BuildAdditionalItems = make([]PersonalItem, 0)
  274. context.Pkg.BuildBudget.MaterialAdditionalItems = make([]PersonalItem, 0)
  275. context.Pkg.BuildBudget.BuildDeductionItems = make([]PersonalItem, 0)
  276. context.Pkg.BuildBudget.MaterialDeductionItems = make([]PersonalItem, 0)
  277. context.Pkg.BuildBudget.MaterialPurchaseItems = make([]PersonalItem, 0)
  278. context.Pkg.BuildBudget.BuildSpecialItems = make([]PersonalItem, 0)
  279. context.Pkg.BuildBudget.PersonalBuildItems = make([]BuildBudgetItem, 0)
  280. for spaceType, items := range PkgItems {
  281. var spaces []Space
  282. if spaceType < 0 {
  283. spaces = []Space{{Area: context.Pkg.RoomData.Pkg.Area}}
  284. } else {
  285. spaces = context.Pkg.RoomData.Space[spaceType]
  286. }
  287. context.SpaceType = spaceType
  288. if _, ok := context.Pkg.BuildBudget.Items[spaceType]; !ok {
  289. context.Pkg.BuildBudget.Items[spaceType] = make([][]BuildBudgetItem, 0)
  290. context.Pkg.BuildBudget.Materials[spaceType] = make([][]MaterialItem, 0)
  291. }
  292. for spaceIndex, space := range spaces {
  293. context.Space = space
  294. context.SpaceIndex = spaceIndex
  295. buildBudgetItems := make([]BuildBudgetItem, 0)
  296. materialItems := make([]MaterialItem, 0)
  297. for n, io := range items {
  298. var regionObject RegionObject
  299. if io.Region == "" {
  300. context.Region = Region{}
  301. } else {
  302. index := -1
  303. for i, o := range Regions[spaceType] {
  304. if o.Name == io.Region {
  305. regionObject = o
  306. index = i
  307. break
  308. }
  309. }
  310. region, ok := context.Pkg.RegionData[spaceType][spaceIndex][index]
  311. if !ok {
  312. if spaceType >= 0 {
  313. for i, o := range Regions[-1] {
  314. if o.Name == io.Region {
  315. regionObject = o
  316. index = i
  317. break
  318. }
  319. }
  320. region, ok = context.Pkg.RegionData[-1][0][index]
  321. }
  322. if !ok {
  323. return errors.New("找不到选材: " + io.Region)
  324. }
  325. }
  326. context.Region = region
  327. }
  328. name, err := io.GetItem(context)
  329. if err != nil {
  330. return err
  331. }
  332. if name == "" {
  333. context.Item = BuildItem{}
  334. } else {
  335. item, ok := context.ItemMap[name]
  336. if !ok {
  337. return errors.New("找不到项目: " + io.Item)
  338. }
  339. context.Item = item
  340. }
  341. number, err := io.GetNumber(context)
  342. context.ItemNumber = number
  343. if err != nil {
  344. return err
  345. }
  346. if number == 0 {
  347. continue
  348. }
  349. deduction := false
  350. for _, d := range context.Pkg.DeductionData[context.SpaceType][context.SpaceIndex] {
  351. if d == n {
  352. deduction = true
  353. break
  354. }
  355. }
  356. price, err := context.Item.GetPrice(context)
  357. if err != nil {
  358. return err
  359. }
  360. if price != 0 {
  361. total := utils.FloatMul(price, number, 3)
  362. if deduction {
  363. context.Pkg.BuildBudget.BuildDeductionItems = append(context.Pkg.BuildBudget.BuildDeductionItems, PersonalItem{
  364. Name: context.GetSpaceName() + " " + context.Item.Name,
  365. Unit: context.Item.Unit,
  366. Number: number,
  367. Price: price,
  368. Total: total,
  369. Remark: context.Item.Remark,
  370. SpaceType: spaceType,
  371. SpaceIndex: spaceIndex,
  372. Index: n,
  373. })
  374. } else {
  375. buildBudgetItems = append(buildBudgetItems, BuildBudgetItem{
  376. Type: context.Item.Type,
  377. Name: context.Item.Name,
  378. Unit: context.Item.Unit,
  379. Number: number,
  380. Price: price,
  381. Total: total,
  382. Remark: context.Item.Remark,
  383. Index: n,
  384. })
  385. context.Pkg.BuildBudget.Cost.Direct = utils.FloatAdd(context.Pkg.BuildBudget.Cost.Direct, total, 3)
  386. diffNumber, err := io.GetDiffNumber(context)
  387. if err != nil {
  388. return err
  389. }
  390. if diffNumber != 0 {
  391. diffPrice, err := io.GetDiffPrice(context)
  392. if err != nil {
  393. return err
  394. }
  395. if diffPrice != 0 {
  396. diffTotal := math.Round(utils.FloatMul(diffPrice, diffNumber, 3))
  397. context.Pkg.BuildBudget.BuildAdditionalItems = append(context.Pkg.BuildBudget.BuildAdditionalItems, PersonalItem{
  398. Type: context.Item.Type,
  399. Name: context.Item.Name + " 升级补差",
  400. Unit: context.Item.Unit,
  401. Number: diffNumber,
  402. Price: diffPrice,
  403. Total: diffTotal,
  404. Index: -1,
  405. })
  406. }
  407. }
  408. }
  409. }
  410. if !deduction {
  411. for _, split := range context.Item.Splits {
  412. total := float64(0)
  413. if split.TotalCalc != nil {
  414. total, err = split.TotalCalc(context, number)
  415. if err != nil {
  416. return err
  417. }
  418. } else {
  419. price := split.Price
  420. if split.PriceCalc != nil {
  421. price, err = split.PriceCalc(context)
  422. if err != nil {
  423. return err
  424. }
  425. }
  426. total = utils.FloatMul(price, number, 3)
  427. }
  428. context.Pkg.BuildBudget.ControlAmount[split.Type] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[split.Type], total, 3)
  429. }
  430. }
  431. if context.Region.Material != 0 || regionObject.MaterialPriceCalc != nil {
  432. typeName := io.Region
  433. if io.MaterialType != "" {
  434. typeName = io.MaterialType
  435. }
  436. if deduction {
  437. pkgNumber, err := io.GetPkgNumber(context)
  438. if err != nil {
  439. return err
  440. }
  441. if pkgNumber != 0 {
  442. deductionPrice, err := io.GetDeductionPrice(context)
  443. if err != nil {
  444. return err
  445. }
  446. //if deductionPrice != 0 {
  447. unit, err := io.GetUnit(context)
  448. if err != nil {
  449. return err
  450. }
  451. total := math.Round(utils.FloatMul(deductionPrice, pkgNumber, 3))
  452. context.Pkg.BuildBudget.MaterialDeductionItems = append(context.Pkg.BuildBudget.MaterialDeductionItems, PersonalItem{
  453. Name: context.GetSpaceName() + " " + typeName,
  454. Unit: unit,
  455. Number: pkgNumber,
  456. Price: deductionPrice,
  457. Total: total,
  458. SpaceType: spaceType,
  459. SpaceIndex: spaceIndex,
  460. Index: n,
  461. })
  462. //}
  463. }
  464. } else {
  465. var mat *final.FinalMat
  466. if context.Region.Material != 0 {
  467. mat = context.GetMat(context.Region.Material)
  468. if mat == nil {
  469. return errors.New("找不到材料: " + db.ToString(context.Region.Material))
  470. }
  471. }
  472. materialPrice := float64(0)
  473. if mat == nil && regionObject.MaterialPriceCalc != nil {
  474. price, err := regionObject.MaterialPriceCalc(context)
  475. if err != nil {
  476. return err
  477. }
  478. materialPrice = price
  479. }
  480. materialNumber, err := io.GetMaterialNumber(context)
  481. if err != nil {
  482. return err
  483. }
  484. if materialNumber == 0 {
  485. continue
  486. }
  487. {
  488. controlPrice := materialPrice
  489. if mat != nil {
  490. controlPrice = mat.ControlPrices()
  491. }
  492. upgradePrice, err := io.GetUpgradePrice(context, controlPrice)
  493. if err != nil {
  494. return err
  495. }
  496. if upgradePrice != 0 {
  497. upgradeNumber, err := io.GetUpgradeNumber(context)
  498. if err != nil {
  499. return err
  500. }
  501. if upgradeNumber != 0 {
  502. matUnit := regionObject.Unit
  503. matName := ""
  504. if mat != nil {
  505. typ := context.GetMatTopType(mat.TypeId)
  506. if typ.ID == 2 {
  507. upgradeNumber = utils.FloatMul(upgradeNumber, 1.1, 2)
  508. }
  509. unit, err := io.GetMatUnit(context, mat)
  510. if err != nil {
  511. return err
  512. }
  513. matUnit = unit
  514. matName = "(" + mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color + ")"
  515. }
  516. upgradeTotal := math.Round(utils.FloatMul(upgradePrice, upgradeNumber, 3))
  517. context.Pkg.BuildBudget.MaterialPurchaseItems = append(context.Pkg.BuildBudget.MaterialPurchaseItems, PersonalItem{
  518. Material: context.Region.Material,
  519. Name: "升级 " + context.GetSpaceName() + " " + typeName + matName,
  520. Unit: matUnit,
  521. Number: upgradeNumber,
  522. Price: upgradePrice,
  523. Total: upgradeTotal,
  524. Index: -1,
  525. })
  526. }
  527. }
  528. }
  529. {
  530. salesPrice := materialPrice
  531. if mat != nil {
  532. salesPrice = mat.SalesPrices()
  533. }
  534. matPrice, err := io.GetMatSalesPrice(context, salesPrice)
  535. if err != nil {
  536. return err
  537. }
  538. if matPrice != 0 {
  539. addNumber, err := io.GetAdditionalNumber(context)
  540. if err != nil {
  541. return err
  542. }
  543. if addNumber != 0 {
  544. matUnit := regionObject.Unit
  545. matName := ""
  546. if mat != nil {
  547. unit, err := io.GetMatUnit(context, mat)
  548. if err != nil {
  549. return err
  550. }
  551. matUnit = unit
  552. matName = "(" + mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color + ")"
  553. }
  554. addTotal := math.Round(utils.FloatMul(matPrice, addNumber, 3))
  555. context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, PersonalItem{
  556. Material: context.Region.Material,
  557. Name: context.GetSpaceName() + " " + typeName + matName,
  558. Unit: matUnit,
  559. Number: addNumber,
  560. Price: matPrice,
  561. Total: addTotal,
  562. Index: -1,
  563. })
  564. }
  565. }
  566. }
  567. if mat != nil {
  568. typ, ok := context.MatTypeCache[mat.TypeId]
  569. if !ok {
  570. return errors.New("找不到材料类型: " + db.ToString(mat.TypeId))
  571. }
  572. total := utils.FloatMul(mat.Price, materialNumber, 3)
  573. costMaterialNumber, err := io.GetCostMaterialNumber(context)
  574. if err != nil {
  575. return err
  576. }
  577. costTotal := utils.FloatMul(mat.Price, costMaterialNumber, 3)
  578. materialItems = append(materialItems, MaterialItem{
  579. Material: context.Region.Material,
  580. Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color,
  581. Type: typeName,
  582. Unit: typ.Unit,
  583. Number: materialNumber,
  584. Price: mat.Price,
  585. Total: total,
  586. CostNumber: costMaterialNumber,
  587. CostTotal: costTotal,
  588. Index: n,
  589. })
  590. }
  591. if io.AdditionalMaterialCalc != nil {
  592. items, err := io.AdditionalMaterialCalc(context)
  593. if err != nil {
  594. return err
  595. }
  596. materialItems = append(materialItems, items...)
  597. }
  598. if io.MaterialAdditionalItemCalc != nil {
  599. items, err := io.MaterialAdditionalItemCalc(context)
  600. if err != nil {
  601. return err
  602. }
  603. context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, items...)
  604. }
  605. }
  606. }
  607. }
  608. context.Pkg.BuildBudget.Items[spaceType] = append(context.Pkg.BuildBudget.Items[spaceType], buildBudgetItems)
  609. context.Pkg.BuildBudget.Materials[spaceType] = append(context.Pkg.BuildBudget.Materials[spaceType], materialItems)
  610. }
  611. }
  612. context.Space = Space{}
  613. context.SpaceType = 0
  614. context.SpaceIndex = 0
  615. context.Item = BuildItem{}
  616. context.ItemNumber = 0
  617. context.Region = Region{}
  618. context.Pkg.BuildBudget.Cost.TransportProportion = 0.025
  619. context.Pkg.BuildBudget.Cost.SanitationProportion = 0.025
  620. context.Pkg.BuildBudget.Cost.ManageProportion = 0.1
  621. context.Pkg.BuildBudget.Cost.AdjustmentNumber = context.Pkg.RoomData.Pkg.Area
  622. context.Pkg.BuildBudget.Cost.AdjustmentPrice = 10
  623. context.Pkg.BuildBudget.Cost.DesignNumber = context.Pkg.RoomData.Pkg.Area
  624. context.Pkg.BuildBudget.Cost.DesignPrice = 15
  625. context.Pkg.BuildBudget.Cost.Transport = utils.FloatMul(context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.TransportProportion, 3)
  626. context.Pkg.BuildBudget.Cost.Sanitation = utils.FloatMul(context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.SanitationProportion, 3)
  627. context.Pkg.BuildBudget.Cost.Manage = utils.FloatMul(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.Transport, context.Pkg.BuildBudget.Cost.Sanitation}, 3), context.Pkg.BuildBudget.Cost.ManageProportion, 3)
  628. context.Pkg.BuildBudget.Cost.Adjustment = utils.FloatMul(context.Pkg.BuildBudget.Cost.AdjustmentNumber, context.Pkg.BuildBudget.Cost.AdjustmentPrice, 3)
  629. context.Pkg.BuildBudget.Cost.Design = utils.FloatMul(context.Pkg.BuildBudget.Cost.DesignNumber, context.Pkg.BuildBudget.Cost.DesignPrice, 3)
  630. context.Pkg.BuildBudget.Cost.Total = utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.Transport, context.Pkg.BuildBudget.Cost.Sanitation, context.Pkg.BuildBudget.Cost.Manage, context.Pkg.BuildBudget.Cost.Adjustment, context.Pkg.BuildBudget.Cost.Design}, 3)
  631. for _, item := range SubsidyItems {
  632. price, err := item.GetPrice(context)
  633. if err != nil {
  634. return err
  635. }
  636. if price == 0 {
  637. continue
  638. }
  639. number, err := item.GetNumber(context)
  640. if err != nil {
  641. return err
  642. }
  643. if number == 0 {
  644. continue
  645. }
  646. total := utils.FloatMul(price, number, 3)
  647. context.Pkg.BuildBudget.SubsidyItems = append(context.Pkg.BuildBudget.SubsidyItems, SubsidyItem{
  648. Name: item.Name,
  649. Unit: item.Unit,
  650. Number: number,
  651. Price: price,
  652. Total: total,
  653. })
  654. context.Pkg.BuildBudget.SubsidyTotal = utils.FloatAdd(context.Pkg.BuildBudget.SubsidyTotal, total, -1)
  655. }
  656. for i, build := range context.Pkg.AdditionalData.Builds {
  657. item, ok := context.ItemMap[build.Item]
  658. if !ok {
  659. return errors.New("找不到项目: " + build.Item)
  660. }
  661. context.Item = item
  662. context.ItemNumber = build.Number
  663. price, err := item.GetPrice(context)
  664. if err != nil {
  665. return err
  666. }
  667. total := math.Round(utils.FloatMul(price, build.Number, 3))
  668. context.Pkg.BuildBudget.BuildAdditionalItems = append(context.Pkg.BuildBudget.BuildAdditionalItems, PersonalItem{
  669. Type: context.Item.Type,
  670. Name: context.Item.Name,
  671. Unit: context.Item.Unit,
  672. Number: build.Number,
  673. Price: price,
  674. Total: total,
  675. Remark: context.Item.Remark,
  676. Index: i,
  677. })
  678. specialProject, err := item.GetSpecialProject(context)
  679. if err != nil {
  680. return err
  681. }
  682. if specialProject {
  683. context.Pkg.BuildBudget.SpecialProjectItems = append(context.Pkg.BuildBudget.SpecialProjectItems, BuildBudgetItem{
  684. Type: context.Item.Type,
  685. Name: context.Item.Name,
  686. Unit: context.Item.Unit,
  687. Number: build.Number,
  688. Price: price,
  689. Total: total,
  690. Remark: context.Item.Remark,
  691. })
  692. context.Pkg.BuildBudget.SpecialProjectTotal = utils.FloatAdd(context.Pkg.BuildBudget.SpecialProjectTotal, total, 3)
  693. } else {
  694. context.Pkg.BuildBudget.PersonalBuildItems = append(context.Pkg.BuildBudget.PersonalBuildItems, BuildBudgetItem{
  695. Type: context.Item.Type,
  696. Name: context.Item.Name,
  697. Unit: context.Item.Unit,
  698. Number: build.Number,
  699. Price: price,
  700. Total: total,
  701. Remark: context.Item.Remark,
  702. })
  703. context.Pkg.BuildBudget.PersonalBuildCost.Direct = utils.FloatAdd(context.Pkg.BuildBudget.PersonalBuildCost.Direct, total, 3)
  704. }
  705. for _, split := range context.Item.Splits {
  706. total := float64(0)
  707. if split.TotalCalc != nil {
  708. total, err = split.TotalCalc(context, build.Number)
  709. if err != nil {
  710. return err
  711. }
  712. } else {
  713. price := split.Price
  714. if split.PriceCalc != nil {
  715. price, err = split.PriceCalc(context)
  716. if err != nil {
  717. return err
  718. }
  719. }
  720. total = utils.FloatMul(price, build.Number, 3)
  721. }
  722. context.Pkg.BuildBudget.ControlAmount[split.Type] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[split.Type], total, 3)
  723. }
  724. }
  725. context.Item = BuildItem{}
  726. context.ItemNumber = 0
  727. context.Pkg.BuildBudget.SubsidyCollect = utils.FloatAdd(context.Pkg.BuildBudget.SubsidyTotal, context.Pkg.BuildBudget.SpecialProjectTotal, -1)
  728. for i, material := range context.Pkg.AdditionalData.Materials {
  729. mat := context.GetMat(material.Material)
  730. if mat == nil {
  731. return errors.New("找不到材料: " + db.ToString(material.Material))
  732. }
  733. typ, ok := context.MatTypeCache[mat.TypeId]
  734. if !ok {
  735. return errors.New("找不到材料类型: " + db.ToString(mat.TypeId))
  736. }
  737. if material.Purchase {
  738. price := mat.PurchasePrices()
  739. total := math.Round(utils.FloatMul(price, material.Number, 3))
  740. context.Pkg.BuildBudget.MaterialPurchaseItems = append(context.Pkg.BuildBudget.MaterialPurchaseItems, PersonalItem{
  741. Material: material.Material,
  742. Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color,
  743. Unit: typ.Unit,
  744. Number: material.Number,
  745. Price: price,
  746. Total: total,
  747. Index: i,
  748. Purchase: material.Purchase,
  749. })
  750. } else {
  751. price := mat.SalesPrices()
  752. total := math.Round(utils.FloatMul(price, material.Number, 3))
  753. context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, PersonalItem{
  754. Material: material.Material,
  755. Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color,
  756. Unit: typ.Unit,
  757. Number: material.Number,
  758. Price: price,
  759. Total: total,
  760. Index: i,
  761. Purchase: material.Purchase,
  762. })
  763. }
  764. total := utils.FloatMul(mat.Price, material.Number, 3)
  765. context.Pkg.BuildBudget.Materials[-1][0] = append(context.Pkg.BuildBudget.Materials[-1][0], MaterialItem{
  766. Material: material.Material,
  767. Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color,
  768. Type: "个性化",
  769. Unit: typ.Unit,
  770. Number: material.Number,
  771. Price: mat.Price,
  772. Total: total,
  773. Index: -1,
  774. })
  775. }
  776. for i, special := range context.Pkg.AdditionalData.Specials {
  777. total := math.Round(utils.FloatMul(special.Price, special.Number, 3))
  778. context.Pkg.BuildBudget.BuildSpecialItems = append(context.Pkg.BuildBudget.BuildSpecialItems, PersonalItem{
  779. Type: special.Type,
  780. Name: special.Name,
  781. Unit: special.Unit,
  782. Number: special.Number,
  783. Price: special.Price,
  784. Total: total,
  785. Remark: special.Remark,
  786. Index: i,
  787. })
  788. context.Pkg.BuildBudget.SpecialProjectItems = append(context.Pkg.BuildBudget.SpecialProjectItems, BuildBudgetItem{
  789. Type: special.Type,
  790. Name: special.Name,
  791. Unit: special.Unit,
  792. Number: special.Number,
  793. Price: special.Price,
  794. Total: total,
  795. Remark: special.Remark,
  796. })
  797. context.Pkg.BuildBudget.SpecialProjectTotal = utils.FloatAdd(context.Pkg.BuildBudget.SpecialProjectTotal, total, 3)
  798. }
  799. for _, AdditionalMaterialFunc := range AdditionalMaterials {
  800. if AdditionalMaterialFunc != nil {
  801. items, err := AdditionalMaterialFunc(context)
  802. if err != nil {
  803. return err
  804. }
  805. if items != nil {
  806. context.Pkg.BuildBudget.Materials[-1][0] = append(context.Pkg.BuildBudget.Materials[-1][0], items...)
  807. }
  808. }
  809. }
  810. for _, MaterialAdditionalItemFunc := range MaterialAdditionalItems {
  811. if MaterialAdditionalItemFunc != nil {
  812. items, err := MaterialAdditionalItemFunc(context)
  813. if err != nil {
  814. return err
  815. }
  816. context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, items...)
  817. }
  818. }
  819. context.Pkg.BuildBudget.PersonalBuildCost.TransportProportion = 0.025
  820. context.Pkg.BuildBudget.PersonalBuildCost.SanitationProportion = 0.025
  821. context.Pkg.BuildBudget.PersonalBuildCost.ManageProportion = 0.1
  822. context.Pkg.BuildBudget.PersonalBuildCost.AdjustmentNumber = context.Pkg.RoomData.Pkg.Area
  823. context.Pkg.BuildBudget.PersonalBuildCost.AdjustmentPrice = 0
  824. context.Pkg.BuildBudget.PersonalBuildCost.DesignNumber = context.Pkg.RoomData.Pkg.Area
  825. context.Pkg.BuildBudget.PersonalBuildCost.DesignPrice = 0
  826. context.Pkg.BuildBudget.PersonalBuildCost.Transport = utils.FloatMul(context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.TransportProportion, 3)
  827. context.Pkg.BuildBudget.PersonalBuildCost.Sanitation = utils.FloatMul(context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.SanitationProportion, 3)
  828. context.Pkg.BuildBudget.PersonalBuildCost.Manage = utils.FloatMul(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.Transport, context.Pkg.BuildBudget.PersonalBuildCost.Sanitation}, 3), context.Pkg.BuildBudget.PersonalBuildCost.ManageProportion, 3)
  829. context.Pkg.BuildBudget.PersonalBuildCost.Total = utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.Transport, context.Pkg.BuildBudget.PersonalBuildCost.Sanitation, context.Pkg.BuildBudget.PersonalBuildCost.Manage, context.Pkg.BuildBudget.PersonalBuildCost.Adjustment, context.Pkg.BuildBudget.PersonalBuildCost.Design}, 3)
  830. pkgs := []int{51, 52, 53, 50}
  831. forms := form.MaterialBidDetailCalc{
  832. Area: context.Pkg.RoomData.Pkg.Area,
  833. FloorNum: 1,
  834. IsElevator: 1,
  835. HouseStyle: make([]structs.HouseStyle, 0),
  836. Param: make([]structs.MaterialBidOrderParam, 0),
  837. PkgID: pkgs[context.Pkg.RoomData.Pkg.Type],
  838. }
  839. for n, layout := range context.Pkg.RoomData.Pkg.Layout {
  840. num := layout
  841. if n == 3 {
  842. num = 1
  843. }
  844. forms.HouseStyle = append(forms.HouseStyle, structs.HouseStyle{
  845. Type: n + 1,
  846. Num: num,
  847. })
  848. }
  849. spaceNames := map[int]string{
  850. 0: "卧室",
  851. 1: "客餐厅",
  852. 2: "厨房",
  853. 3: "卫生间",
  854. 4: "阳台",
  855. }
  856. for typ, spaces := range context.Pkg.RoomData.Space {
  857. //if typ == 3 {
  858. // spaces = []Space{spaces[0]}
  859. //}
  860. for n, space := range spaces {
  861. forms.Param = append(forms.Param, structs.MaterialBidOrderParam{
  862. Area: space.Area,
  863. Round: space.Perimeter,
  864. RoomName: spaceNames[typ] + db.ToString(n+1),
  865. RoomType: typ + 1,
  866. })
  867. }
  868. }
  869. res, err := bid.Calc(forms)
  870. if err != nil {
  871. return err
  872. }
  873. context.Pkg.BuildBudget.Contract.PkgPrice = math.Round(res.TotalPrice)
  874. context.Pkg.BuildBudget.Contract.PkgTotal = math.Round(res.TotalPrice)
  875. context.Pkg.BuildBudget.Contract.ToiletPrice = make([]float64, 0)
  876. /*for n, space := range context.Pkg.RoomData.Space[3] {
  877. if n == 0 {
  878. continue
  879. }
  880. form1 := form.MaterialBidDetailCalc1{
  881. PkgID: pkgs[context.Pkg.RoomData.Pkg.Type],
  882. Area: space.Area,
  883. Round: space.Perimeter,
  884. }
  885. res, err := bid.CalcToilet(form1)
  886. if err != nil {
  887. return err
  888. }
  889. context.Pkg.BuildBudget.Contract.ToiletPrice = append(context.Pkg.BuildBudget.Contract.ToiletPrice, res.TotalPrice)
  890. context.Pkg.BuildBudget.Contract.PkgTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.PkgTotal, res.TotalPrice, -1)
  891. }*/
  892. for _, material := range context.Pkg.BuildBudget.MaterialAdditionalItems {
  893. context.Pkg.BuildBudget.Contract.MaterialTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialTotal, material.Total, -1)
  894. }
  895. for _, item := range context.Pkg.BuildBudget.BuildAdditionalItems {
  896. context.Pkg.BuildBudget.Contract.PersonalBuildTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.PersonalBuildTotal, item.Total, -1)
  897. }
  898. //context.Pkg.BuildBudget.Contract.PersonalBuildTotal = context.Pkg.BuildBudget.PersonalBuildCost.Direct
  899. context.Pkg.BuildBudget.Contract.PersonalAmount = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialTotal, context.Pkg.BuildBudget.Contract.PersonalBuildTotal, -1)
  900. context.Pkg.BuildBudget.Contract.PersonalTransportProportion = 0.025
  901. context.Pkg.BuildBudget.Contract.PersonalSanitationProportion = 0.025
  902. context.Pkg.BuildBudget.Contract.PersonalManageProportion = 0.1
  903. context.Pkg.BuildBudget.Contract.PersonalTransport = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalTransportProportion, 3))
  904. context.Pkg.BuildBudget.Contract.PersonalSanitation = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalSanitationProportion, 3))
  905. context.Pkg.BuildBudget.Contract.PersonalManage = math.Round(utils.FloatMul(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalTransport, context.Pkg.BuildBudget.Contract.PersonalSanitation}, 3), context.Pkg.BuildBudget.Contract.PersonalManageProportion, 3))
  906. context.Pkg.BuildBudget.Contract.PersonalTotal = math.Round(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalTransport, context.Pkg.BuildBudget.Contract.PersonalSanitation, context.Pkg.BuildBudget.Contract.PersonalManage}, 3))
  907. context.Pkg.BuildBudget.Contract.DesignPrice = math.Round(utils.FloatMul(context.Pkg.ContractData.Design, context.Pkg.RoomData.Pkg.Area, -1))
  908. context.Pkg.BuildBudget.Contract.ChartPrice = math.Round(utils.FloatMul(context.Pkg.ContractData.Chart, context.Pkg.RoomData.Pkg.Area, -1))
  909. //context.Pkg.BuildBudget.Contract.DesignTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.DesignPrice, context.Pkg.BuildBudget.Contract.ChartPrice, -1)
  910. context.Pkg.BuildBudget.Contract.DirectTotal = math.Round(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Contract.PkgTotal, context.Pkg.BuildBudget.Contract.PersonalTotal, context.Pkg.BuildBudget.Contract.ChartPrice, context.Pkg.BuildBudget.Contract.DesignPrice}, -1))
  911. context.Pkg.BuildBudget.Contract.DirectCost = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.DirectTotal, context.Pkg.ContractData.Discount, -1))
  912. for _, material := range context.Pkg.BuildBudget.MaterialPurchaseItems {
  913. context.Pkg.BuildBudget.Contract.MaterialPurchaseTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialPurchaseTotal, material.Total, -1)
  914. }
  915. for _, item := range context.Pkg.BuildBudget.BuildSpecialItems {
  916. context.Pkg.BuildBudget.Contract.SpecialProjectTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.SpecialProjectTotal, item.Total, -1)
  917. }
  918. context.Pkg.BuildBudget.Contract.PurchaseTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialPurchaseTotal, context.Pkg.BuildBudget.Contract.SpecialProjectTotal, -1)
  919. for _, material := range context.Pkg.BuildBudget.MaterialDeductionItems {
  920. context.Pkg.BuildBudget.Contract.MaterialDeductionTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialDeductionTotal, material.Total, -1)
  921. }
  922. for _, material := range context.Pkg.BuildBudget.BuildDeductionItems {
  923. context.Pkg.BuildBudget.Contract.BuildDeductionTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.BuildDeductionTotal, material.Total, -1)
  924. }
  925. context.Pkg.BuildBudget.PackageAmount = utils.FloatMulSlice([]float64{utils.FloatAdd(context.Pkg.BuildBudget.Cost.Total, context.Pkg.BuildBudget.PersonalBuildCost.Total, -1), 0.9, 0.63}, -1)
  926. context.Pkg.BuildBudget.ControlAmount[沙石材料] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[沙石材料], utils.FloatMul(context.Pkg.BuildBudget.PackageAmount, 0.12, -1), 3)
  927. tzArea := float64(0)
  928. for _, itemss := range context.Pkg.BuildBudget.Items {
  929. for _, items := range itemss {
  930. for _, item := range items {
  931. if strings.Contains(item.Name, "贴砖") {
  932. tzArea = utils.FloatAdd(tzArea, item.Number, -1)
  933. }
  934. }
  935. }
  936. }
  937. context.Pkg.BuildBudget.ControlAmount[开工形象] = 630
  938. tzArea = utils.FloatSub(tzArea, 50, -1)
  939. for tzArea > 0 {
  940. context.Pkg.BuildBudget.ControlAmount[开工形象] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[开工形象], 160, -1)
  941. tzArea = utils.FloatSub(tzArea, 50, -1)
  942. }
  943. for _, item := range context.Pkg.BuildBudget.BuildSpecialItems {
  944. context.Pkg.BuildBudget.ControlAmount[item.Type] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[item.Type], item.Total, -1)
  945. }
  946. context.Pkg.BuildBudget.Contract.Cost = math.Round(utils.FloatAdd(context.Pkg.BuildBudget.Contract.DirectCost, context.Pkg.BuildBudget.Contract.PurchaseTotal, -1))
  947. if context.Pkg.ContractData.Taxes {
  948. context.Pkg.BuildBudget.Contract.Taxes = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.Cost, 0.036, -1))
  949. }
  950. context.Pkg.BuildBudget.Contract.CostTotal = math.Round(utils.FloatAdd(context.Pkg.BuildBudget.Contract.Cost, context.Pkg.BuildBudget.Contract.Taxes, -1))
  951. for _, materialss := range context.Pkg.BuildBudget.Materials {
  952. for _, materials := range materialss {
  953. for _, material := range materials {
  954. context.Pkg.BuildBudget.MaterialCost = utils.FloatAdd(context.Pkg.BuildBudget.MaterialCost, material.CostTotal, -1)
  955. }
  956. }
  957. }
  958. context.Pkg.BuildBudget.MaterialCost = utils.FloatAdd(context.Pkg.BuildBudget.MaterialCost, context.Pkg.BuildBudget.ControlAmount[开关面板], -1)
  959. context.Pkg.BuildBudget.Profit = utils.FloatSubSlice([]float64{context.Pkg.BuildBudget.Contract.Cost, context.Pkg.BuildBudget.Contract.MaterialDeductionTotal, context.Pkg.BuildBudget.Contract.BuildDeductionTotal, context.Pkg.BuildBudget.PackageAmount, context.Pkg.BuildBudget.SubsidyCollect, context.Pkg.BuildBudget.MaterialCost, 1500}, -1)
  960. context.Pkg.BuildBudget.ProfitMargin = utils.FloatDiv(context.Pkg.BuildBudget.Profit, context.Pkg.BuildBudget.Contract.CostTotal, -1)
  961. return nil
  962. }