GoodERP
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

150 行
5.8KB

  1. # Copyright 2016 上海开阖软件有限公司 (http://www.osbzr.com)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo import api, fields, models, _
  4. '''
  5. 会计月末的成本核算方法
  6. 库存收发明细表全部使用个别计价
  7. 月末结账时再根据此核算方法生成发出成本差异凭证
  8. '''
  9. CORE_COST_METHOD = [('average', '全月一次加权平均法'),
  10. ('std', '定额成本'),
  11. ('fifo', '个别计价法'),
  12. ]
  13. AVAILABLE_PRIORITIES = [
  14. ('0', 'E'),
  15. ('1', 'D'),
  16. ('2', 'C'),
  17. ('3', 'B'),
  18. ('4', 'A'),
  19. ]
  20. class Goods(models.Model):
  21. _name = 'goods'
  22. _description = '商品'
  23. _inherit = ['mail.thread', 'mail.activity.mixin']
  24. _order = 'priority desc'
  25. @api.model
  26. def _get_default_not_saleable_impl(self):
  27. return False
  28. @api.model
  29. def _get_default_not_saleable(self):
  30. return self._get_default_not_saleable_impl()
  31. @api.model
  32. def _get_default_not_buyable_impl(self):
  33. return False
  34. @api.model
  35. def _get_default_not_buyable(self):
  36. return self._get_default_not_buyable_impl()
  37. def name_get(self):
  38. '''在many2one字段里显示 编号_名称'''
  39. res = []
  40. for Goods in self:
  41. res.append((Goods.id, Goods.code and (
  42. Goods.code + '_' + Goods.name) or Goods.name))
  43. return res
  44. @api.depends('code', 'name')
  45. def _compute_display_name(self):
  46. '''在many2one字段里显示 编号_名称, 注意原来的 name_get 被name_search使用, 不能删除'''
  47. for record in self:
  48. record.display_name= record.code and (record.code + '_' + record.name) or record.name
  49. @api.model
  50. def name_search(self, name='', args=None, operator='ilike', limit=100):
  51. '''在many2one字段中支持按编号搜索'''
  52. args = args or []
  53. code_search_goods = []
  54. if name:
  55. goods_id = self.search([('code', '=', name)])
  56. if goods_id:
  57. return goods_id.name_get()
  58. args.append(('code', 'ilike', name))
  59. goods_ids = self.search(args)
  60. if goods_ids:
  61. code_search_goods = goods_ids.name_get()
  62. args.remove(('code', 'ilike', name))
  63. search_goods = super(Goods, self).name_search(
  64. name=name, args=args,
  65. operator=operator, limit=limit
  66. )
  67. for good_tup in code_search_goods: # 去除重复产品
  68. if good_tup not in search_goods:
  69. search_goods.append(good_tup)
  70. return search_goods
  71. @api.model_create_multi
  72. def create(self, vals_list):
  73. '''导入商品时,如果辅助单位为空,则用计量单位来填充它'''
  74. for vals in vals_list:
  75. if not vals.get('uos_id'):
  76. vals.update({'uos_id': vals.get('uom_id')})
  77. return super().create(vals_list)
  78. def copy(self, default=None):
  79. ''' 避免复制时提示名称和编号不可重复 '''
  80. if default is None:
  81. default = {}
  82. if 'name' not in default:
  83. default.update(name=_('%s (copy)') % (self.name))
  84. if self.code and 'code' not in default:
  85. default.update(code=_('%s (copy)') % (self.code))
  86. return super(Goods, self).copy(default=default)
  87. display_name = fields.Char(compute='_compute_display_name', store=True)
  88. code = fields.Char('编号')
  89. name = fields.Char('名称', required=True, copy=False)
  90. priority = fields.Selection(AVAILABLE_PRIORITIES, '商品重要性', default='0')
  91. category_id = fields.Many2one('core.category', '核算类别',
  92. ondelete='restrict',
  93. domain=[('type', '=', 'goods')],
  94. required=True,
  95. help='从会计科目角度划分的类别',
  96. )
  97. uom_id = fields.Many2one('uom', ondelete='restrict',
  98. string='计量单位', required=True)
  99. uos_id = fields.Many2one('uom', ondelete='restrict', string='辅助单位')
  100. conversion = fields.Float(
  101. string='转化率', default=1, digits=(16, 3),
  102. help='1个辅助单位等于多少计量单位的数量,如1箱30个苹果,这里就输入30')
  103. cost = fields.Float('成本',
  104. digits='Price')
  105. cost_method = fields.Selection(CORE_COST_METHOD, '存货计价方法',
  106. help='''GoodERP仓库模块使用先进先出规则匹配
  107. 每次出库对应的入库成本和数量,但不实时记账。
  108. 财务月结时使用此方法相应调整发出成本''')
  109. tax_rate = fields.Float('税率(%)',
  110. help='商品税率')
  111. not_saleable = fields.Boolean('不可销售',
  112. default=_get_default_not_saleable,
  113. help='商品是否不可销售,勾选了就不可销售,未勾选可销售')
  114. not_buyable = fields.Boolean('不可采购',
  115. default=_get_default_not_buyable,
  116. help='商品是否不可采购,勾选了就不可采购,未勾选可采购')
  117. active = fields.Boolean('启用', default=True)
  118. company_id = fields.Many2one(
  119. 'res.company',
  120. string='公司',
  121. change_default=True,
  122. default=lambda self: self.env.company)
  123. brand = fields.Many2one('core.value', '品牌',
  124. ondelete='restrict',
  125. domain=[('type', '=', 'brand')],
  126. context={'type': 'brand'})
  127. size = fields.Char('尺寸')
  128. _sql_constraints = [
  129. ('conversion_no_zero', 'check(conversion != 0)', '商品的转化率不能为0')
  130. ]
上海开阖软件有限公司 沪ICP备12045867号-1