item.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. package pkg2024
  2. import (
  3. "math"
  4. "zhiyuan/models/final"
  5. "zhiyuan/pkg/utils"
  6. )
  7. const (
  8. 拆除 int = iota
  9. 水电
  10. 泥工
  11. 木工
  12. 油漆
  13. 防水
  14. 封包管道
  15. 其他
  16. 水电基础
  17. 水电安装
  18. 水电材料
  19. 油漆材料
  20. 木工材料
  21. 沙石材料
  22. 开工形象
  23. 开关面板
  24. 杂费
  25. )
  26. type ItemStringFunction func(context *ItemContext) (string, error)
  27. type ItemNumberFunction func(context *ItemContext) (float64, error)
  28. type ItemTotalFunction func(context *ItemContext, number float64) (float64, error)
  29. type ItemJudgmentFunction func(context *ItemContext) (bool, error)
  30. type ItemIntFunction func(context *ItemContext) (int64, error)
  31. type ItemPersonalFunction func(context *ItemContext) ([]PersonalItem, error)
  32. type ItemMaterialFunction func(context *ItemContext) ([]MaterialItem, error)
  33. type SplitItem struct {
  34. Type int
  35. Price float64
  36. PriceCalc ItemNumberFunction
  37. TotalCalc ItemTotalFunction
  38. }
  39. type BuildItem struct {
  40. Name string
  41. Type int
  42. Price float64
  43. PriceCalc ItemNumberFunction
  44. MaterialNumberCalc ItemJudgmentFunction
  45. Unit string
  46. Remark string
  47. Splits []SplitItem
  48. SpecialProject bool
  49. SpecialProjectCalc ItemJudgmentFunction
  50. }
  51. func (item BuildItem) GetPrice(context *ItemContext) (float64, error) {
  52. if item.PriceCalc != nil {
  53. return item.PriceCalc(context)
  54. }
  55. return item.Price, nil
  56. }
  57. func (item BuildItem) GetSpecialProject(context *ItemContext) (bool, error) {
  58. if item.SpecialProjectCalc != nil {
  59. return item.SpecialProjectCalc(context)
  60. }
  61. return item.SpecialProject, nil
  62. }
  63. type PkgItemObject struct {
  64. Item string
  65. ItemSelect ItemStringFunction
  66. Number float64
  67. NumberCalc ItemNumberFunction
  68. PkgNumber float64
  69. PkgNumberCalc ItemNumberFunction
  70. Loss float64
  71. LossCalc ItemNumberFunction
  72. Convert float64
  73. ConvertCalc ItemNumberFunction
  74. MaterialNumberCalc ItemNumberFunction
  75. Region string
  76. Unit string
  77. UnitCalc ItemStringFunction
  78. MaterialType string
  79. MaterialRound bool
  80. ControlPrice map[int]float64
  81. ControlPriceCalc ItemNumberFunction
  82. DeductionPrice map[int]float64
  83. DeductionPriceCalc ItemNumberFunction
  84. DiffPrice map[int]float64
  85. DiffPriceCalc ItemNumberFunction
  86. MaterialAdditionalItemCalc ItemPersonalFunction
  87. AdditionalMaterialCalc ItemMaterialFunction
  88. CostLoss float64
  89. CostLossCalc ItemNumberFunction
  90. NoUpgrade bool
  91. }
  92. func (pkgItem PkgItemObject) GetLoss(context *ItemContext) (float64, error) {
  93. if pkgItem.LossCalc != nil {
  94. return pkgItem.LossCalc(context)
  95. }
  96. if pkgItem.Loss == 0 {
  97. return 1, nil
  98. }
  99. return pkgItem.Loss, nil
  100. }
  101. func (pkgItem PkgItemObject) GetCostLoss(context *ItemContext) (float64, error) {
  102. if pkgItem.CostLossCalc != nil {
  103. return pkgItem.CostLossCalc(context)
  104. }
  105. if pkgItem.CostLoss != 0 {
  106. return pkgItem.CostLoss, nil
  107. }
  108. return pkgItem.GetLoss(context)
  109. }
  110. func (pkgItem PkgItemObject) GetConvert(context *ItemContext) (float64, error) {
  111. if pkgItem.ConvertCalc != nil {
  112. return pkgItem.ConvertCalc(context)
  113. }
  114. if pkgItem.Convert == 0 {
  115. return 1, nil
  116. }
  117. return pkgItem.Convert, nil
  118. }
  119. func (pkgItem PkgItemObject) GetLossNumber(context *ItemContext) (float64, error) {
  120. number, err := pkgItem.GetNumber(context)
  121. if err != nil {
  122. return 0, err
  123. }
  124. loss, err := pkgItem.GetLoss(context)
  125. if err != nil {
  126. return 0, err
  127. }
  128. return utils.FloatMul(number, loss, -1), nil
  129. }
  130. func (pkgItem PkgItemObject) GetCostLossNumber(context *ItemContext) (float64, error) {
  131. number, err := pkgItem.GetNumber(context)
  132. if err != nil {
  133. return 0, err
  134. }
  135. if number < 0 {
  136. number = 0
  137. }
  138. loss, err := pkgItem.GetCostLoss(context)
  139. if err != nil {
  140. return 0, err
  141. }
  142. return utils.FloatMul(number, loss, -1), nil
  143. }
  144. func (pkgItem PkgItemObject) GetCostMaterialNumber(context *ItemContext) (float64, error) {
  145. if pkgItem.MaterialNumberCalc != nil {
  146. return pkgItem.MaterialNumberCalc(context)
  147. }
  148. number, err := pkgItem.GetCostLossNumber(context)
  149. if err != nil {
  150. return 0, err
  151. }
  152. convert, err := pkgItem.GetConvert(context)
  153. if err != nil {
  154. return 0, err
  155. }
  156. number = utils.FloatMul(number, convert, -1)
  157. if pkgItem.MaterialRound {
  158. number = math.Ceil(number)
  159. }
  160. return number, nil
  161. }
  162. func (pkgItem PkgItemObject) GetMaterialNumber(context *ItemContext) (float64, error) {
  163. if pkgItem.MaterialNumberCalc != nil {
  164. return pkgItem.MaterialNumberCalc(context)
  165. }
  166. number, err := pkgItem.GetLossNumber(context)
  167. if err != nil {
  168. return 0, err
  169. }
  170. convert, err := pkgItem.GetConvert(context)
  171. if err != nil {
  172. return 0, err
  173. }
  174. number = utils.FloatMul(number, convert, -1)
  175. if pkgItem.MaterialRound {
  176. number = math.Ceil(number)
  177. }
  178. return number, nil
  179. }
  180. func (pkgItem PkgItemObject) GetItem(context *ItemContext) (string, error) {
  181. if pkgItem.ItemSelect != nil {
  182. return pkgItem.ItemSelect(context)
  183. }
  184. return pkgItem.Item, nil
  185. }
  186. func (pkgItem PkgItemObject) GetNumber(context *ItemContext) (float64, error) {
  187. number := pkgItem.Number
  188. if pkgItem.NumberCalc != nil {
  189. var err error
  190. number, err = pkgItem.NumberCalc(context)
  191. if err != nil {
  192. return number, nil
  193. }
  194. }
  195. if number < 0 {
  196. number = 0
  197. }
  198. return number, nil
  199. }
  200. func (pkgItem PkgItemObject) GetPkgNumber(context *ItemContext) (float64, error) {
  201. if pkgItem.PkgNumberCalc != nil {
  202. return pkgItem.PkgNumberCalc(context)
  203. }
  204. if pkgItem.PkgNumber != 0 {
  205. return pkgItem.PkgNumber, nil
  206. }
  207. if pkgItem.NumberCalc != nil {
  208. return pkgItem.NumberCalc(context)
  209. }
  210. return pkgItem.Number, nil
  211. }
  212. func (pkgItem PkgItemObject) GetControlPrice(context *ItemContext) (float64, error) {
  213. if pkgItem.ControlPriceCalc != nil {
  214. return pkgItem.ControlPriceCalc(context)
  215. }
  216. return pkgItem.ControlPrice[context.Pkg.RoomData.Pkg.Type], nil
  217. }
  218. func (pkgItem PkgItemObject) GetDeductionPrice(context *ItemContext) (float64, error) {
  219. if pkgItem.DeductionPriceCalc != nil {
  220. return pkgItem.DeductionPriceCalc(context)
  221. }
  222. return pkgItem.DeductionPrice[context.Pkg.RoomData.Pkg.Type], nil
  223. }
  224. func (pkgItem PkgItemObject) GetUnit(context *ItemContext) (string, error) {
  225. if pkgItem.UnitCalc != nil {
  226. return pkgItem.UnitCalc(context)
  227. }
  228. return pkgItem.Unit, nil
  229. }
  230. func (pkgItem PkgItemObject) GetMatUnit(context *ItemContext, mat *final.FinalMat) (string, error) {
  231. unit, err := pkgItem.GetUnit(context)
  232. if err != nil {
  233. return unit, err
  234. }
  235. if unit != "" {
  236. return unit, nil
  237. }
  238. if mat != nil {
  239. typ, ok := context.MatTypeCache[mat.TypeId]
  240. if ok {
  241. return typ.Unit, nil
  242. }
  243. }
  244. return "", nil
  245. }
  246. func (pkgItem PkgItemObject) GetMatPrice(context *ItemContext, mat *final.FinalMat) (float64, error) {
  247. convert, err := pkgItem.GetConvert(context)
  248. if err != nil {
  249. return 0, err
  250. }
  251. matPrice := utils.FloatMul(mat.Price, convert, 3)
  252. return matPrice, nil
  253. }
  254. func (pkgItem PkgItemObject) GetMatSalesPrice(context *ItemContext, salesPrice float64) (float64, error) {
  255. convert, err := pkgItem.GetConvert(context)
  256. if err != nil {
  257. return 0, err
  258. }
  259. matMatSalesPrice := utils.FloatMul(salesPrice, convert, -1)
  260. return matMatSalesPrice, nil
  261. }
  262. func (pkgItem PkgItemObject) GetMatPurchasePrice(context *ItemContext, mat *final.FinalMat) (float64, error) {
  263. convert, err := pkgItem.GetConvert(context)
  264. if err != nil {
  265. return 0, err
  266. }
  267. matMatPurchasePrice := utils.FloatMul(final.PurchasePrice(mat.PurchasePrice, mat.Price), convert, -1)
  268. return matMatPurchasePrice, nil
  269. }
  270. func (pkgItem PkgItemObject) GetUpgradePrice(context *ItemContext, matControlPrice float64) (float64, error) {
  271. if pkgItem.NoUpgrade {
  272. return 0, nil
  273. }
  274. controlPrice, err := pkgItem.GetControlPrice(context)
  275. if err != nil {
  276. return 0, err
  277. }
  278. convert, err := pkgItem.GetConvert(context)
  279. if err != nil {
  280. return 0, err
  281. }
  282. matControlPrice = utils.FloatMul(matControlPrice, convert, -1)
  283. if matControlPrice > controlPrice {
  284. return math.Ceil(utils.FloatDiv(utils.FloatSub(matControlPrice, controlPrice, -1), 0.84, -1)*100) / 100, nil
  285. }
  286. return 0, nil
  287. }
  288. func (pkgItem PkgItemObject) GetUpgradeNumber(context *ItemContext) (float64, error) {
  289. lossNumber, err := pkgItem.GetLossNumber(context)
  290. if err != nil {
  291. return 0, err
  292. }
  293. pkgNumber, err := pkgItem.GetPkgNumber(context)
  294. if err != nil {
  295. return 0, err
  296. }
  297. if lossNumber > pkgNumber {
  298. return pkgNumber, nil
  299. }
  300. return lossNumber, nil
  301. }
  302. func (pkgItem PkgItemObject) GetPkgLossNumber(context *ItemContext) (float64, error) {
  303. number, err := pkgItem.GetPkgNumber(context)
  304. if err != nil {
  305. return 0, err
  306. }
  307. loss, err := pkgItem.GetLoss(context)
  308. if err != nil {
  309. return 0, err
  310. }
  311. return utils.FloatMul(number, loss, -1), nil
  312. }
  313. func (pkgItem PkgItemObject) GetAdditionalNumber(context *ItemContext) (float64, error) {
  314. lossNumber, err := pkgItem.GetLossNumber(context)
  315. if err != nil {
  316. return 0, err
  317. }
  318. pkgLossNumber, err := pkgItem.GetPkgLossNumber(context)
  319. if err != nil {
  320. return 0, err
  321. }
  322. if lossNumber > pkgLossNumber {
  323. return utils.FloatSub(lossNumber, pkgLossNumber, -1), nil
  324. }
  325. return 0, nil
  326. }
  327. func (pkgItem PkgItemObject) GetDiffPrice(context *ItemContext) (float64, error) {
  328. if pkgItem.DiffPriceCalc != nil {
  329. return pkgItem.DiffPriceCalc(context)
  330. }
  331. return pkgItem.DiffPrice[context.Pkg.RoomData.Pkg.Type], nil
  332. }
  333. func (pkgItem PkgItemObject) GetDiffNumber(context *ItemContext) (float64, error) {
  334. number, err := pkgItem.GetNumber(context)
  335. if err != nil {
  336. return 0, err
  337. }
  338. pkgNumber, err := pkgItem.GetPkgNumber(context)
  339. if err != nil {
  340. return 0, err
  341. }
  342. if number > pkgNumber {
  343. return pkgNumber, nil
  344. }
  345. return number, nil
  346. }
  347. type SubsidyItemObject struct {
  348. Name string
  349. Unit string
  350. Number float64
  351. NumberCalc ItemNumberFunction
  352. Price float64
  353. PriceCalc ItemNumberFunction
  354. }
  355. func (subsidyItem SubsidyItemObject) GetNumber(context *ItemContext) (float64, error) {
  356. if subsidyItem.NumberCalc != nil {
  357. return subsidyItem.NumberCalc(context)
  358. }
  359. return subsidyItem.Number, nil
  360. }
  361. func (subsidyItem SubsidyItemObject) GetPrice(context *ItemContext) (float64, error) {
  362. if subsidyItem.PriceCalc != nil {
  363. return subsidyItem.PriceCalc(context)
  364. }
  365. return subsidyItem.Price, nil
  366. }