GoodERP
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

105 lignes
4.1KB

  1. from odoo import api, fields, models
  2. from odoo.exceptions import UserError
  3. class Warehouse(models.Model):
  4. _name = 'warehouse'
  5. _description = '仓库'
  6. # 用户只能创建stock类型的仓库
  7. WAREHOUSE_TYPE = [
  8. ('stock', '库存'),
  9. ('supplier', '供应商'),
  10. ('customer', '客户'),
  11. ('inventory', '盘点'),
  12. ('production', '生产'),
  13. ('others', '其他'),
  14. ]
  15. display_name = fields.Char(compute='_compute_display_name', store=True)
  16. name = fields.Char('名称', required=True)
  17. code = fields.Char('编号')
  18. type = fields.Selection(WAREHOUSE_TYPE, '类型', default='stock')
  19. active = fields.Boolean('启用', default=True)
  20. user_ids = fields.Many2many('res.users', string='库管')
  21. address = fields.Char('地址')
  22. phone = fields.Char('电话')
  23. contact = fields.Char('联系人')
  24. company_id = fields.Many2one(
  25. 'res.company',
  26. string='公司',
  27. change_default=True,
  28. default=lambda self: self.env.company)
  29. _sql_constraints = [
  30. ('name_uniq', 'unique(name)', '仓库不能重名')
  31. ]
  32. @api.model
  33. def name_search(self, name='', args=None, operator='ilike', limit=100):
  34. ''' 让warehouse支持使用code来搜索'''
  35. args = args or []
  36. # 将name当成code搜
  37. if name and not [_type for _type in args if _type[0] == 'code']:
  38. warehouses = self.search(
  39. [('type', '=', 'stock'), ('code', 'ilike', name)])
  40. if warehouses:
  41. return warehouses.name_get()
  42. # 下拉列表只显示stock类型的仓库
  43. if not [_type for _type in args if _type[0] == 'type']:
  44. # 检查是否在导入场景中(导入时允许使用 Inventory)
  45. if not self.env.context.get('import_file') and \
  46. not self.env.context.get('all_type'):
  47. args = [['type', '=', 'stock']] + args
  48. return super(Warehouse, self).name_search(
  49. name=name, args=args,
  50. operator=operator, limit=limit)
  51. def name_get(self):
  52. '''将仓库显示为 [编号]名字 的形式'''
  53. res = []
  54. for Warehouse in self:
  55. res.append((Warehouse.id, '[%s]%s' %
  56. (Warehouse.code, Warehouse.name)))
  57. return res
  58. @api.depends('code', 'name')
  59. def _compute_display_name(self):
  60. '''将仓库显示为 [编号]名字 的形式, 注意原来的 name_get 被name_search使用, 不能删除'''
  61. for record in self:
  62. record.display_name= record.code and (record.code + '_' + record.name) or record.name
  63. def get_warehouse_by_type(self, _type, need_user_ids=True):
  64. '''返回指定类型的第一个仓库'''
  65. if not _type or _type not in [
  66. _type[0] for _type in self.WAREHOUSE_TYPE]:
  67. raise UserError('仓库类型" % s"不在预先定义的type之中,请联系管理员' % _type)
  68. domain = [('type', '=', _type)]
  69. # 仓库管理员带出有权限的仓库作为默认值
  70. if _type == 'stock' and self.env.user.has_group('warehouse.group_warehouse') and need_user_ids:
  71. # 由于权限组在仓库模块,这里core模块测试用例测不到
  72. domain += ['|', ('user_ids', '=', False),
  73. ('user_ids', 'in', self._uid)]
  74. warehouses = self.search(domain, limit=1, order='id asc')
  75. if not warehouses:
  76. raise UserError('不存在类型为%s的仓库,请检查基础数据是否全部导入' % _type)
  77. return warehouses[0]
  78. def write(self, vals):
  79. # 如果仓库里存有商品,则禁止此仓库存档并提示错误
  80. if 'active' in vals and not vals['active']:
  81. name_list = []
  82. for line in self:
  83. name_list.append(line.name)
  84. stock = self.env['report.stock.balance'].search([('warehouse', 'in', name_list), ('goods_qty', '!=', 0)])
  85. name_list = []
  86. for li in stock:
  87. name_list.append(li.warehouse)
  88. raise UserError('仓库名称为%s的仓库库存不为0' % str(set(name_list)))
  89. return super().write(vals)
上海开阖软件有限公司 沪ICP备12045867号-1