|
-
- from .utils import inherits, inherits_after, create_name, create_origin
-
- from odoo import models, fields, api
- from odoo.exceptions import UserError
- import logging
- _logger = logging.getLogger(__name__)
-
-
- class WhOut(models.Model):
- _name = 'wh.out'
- _description = '其他出库单'
- _inherit = ['mail.thread', 'barcodes.barcode_events_mixin']
- _order = 'date DESC, id DESC'
-
- _inherits = {
- 'wh.move': 'move_id',
- }
-
- TYPE_SELECTION = [
- ('inventory', '盘亏'),
- ('others', '其他出库'),
- ('cancel', '已作废')]
-
- move_id = fields.Many2one('wh.move', '移库单', required=True, index=True, ondelete='cascade',
- help='其他出库单对应的移库单')
- type = fields.Selection(TYPE_SELECTION, '业务类别', default='others',
- help='类别: 盘亏,其他出库')
- amount_total = fields.Float(compute='_get_amount_total', string='合计成本金额',
- store=True, readonly=True, digits='Amount',
- help='该出库单的出库金额总和')
- voucher_id = fields.Many2one('voucher', '出库凭证',
- readonly=True,
- help='该出库单的后生成的出库凭证')
-
- @inherits_after()
- def approve_order(self):
- for order in self:
- if order.state == 'done':
- raise UserError('请不要重复出库')
- if self.env.user.company_id.is_enable_negative_stock: # 其他出库单检查负库存
- result_vals = self.env['wh.move'].create_zero_wh_in(self, self._name)
- if result_vals:
- return result_vals
- voucher = order.create_voucher()
- order.write({
- 'voucher_id': voucher and voucher[0] and voucher[0].id,
- 'state': 'done',
- })
- return True
-
- @inherits()
- def cancel_approved_order(self):
- for order in self:
- if order.state == 'draft':
- raise UserError('请不要重复撤销 %s' % self._description)
- order.delete_voucher()
- order.state = 'draft'
- return True
-
- @inherits()
- def unlink(self):
- for order in self:
- return order.move_id.unlink()
-
- @api.depends('line_out_ids.cost')
- def _get_amount_total(self):
- for wo in self:
- wo.amount_total = sum(line.cost for line in wo.line_out_ids)
-
- def get_move_origin(self, vals):
- return self._name + '.' + vals.get('type')
-
- @api.model
- @create_name
- @create_origin
- def create(self, vals):
- return super(WhOut, self).create(vals)
-
- @api.onchange('type')
- def onchange_type(self):
- self.warehouse_dest_id = self.env['warehouse'].get_warehouse_by_type(
- self.type)
-
- def goods_inventory(self, vals):
- """
- 审核时若仓库中商品不足,则产生补货向导生成其他入库单并审核。
- :param vals: 创建其他入库单需要的字段及取值信息构成的字典
- :return:
- """
- auto_in = self.env['wh.in'].create(vals)
- self.with_context({'wh_in_line_ids': [line.id for line in
- auto_in.line_in_ids]}).approve_order()
-
- def create_voucher(self):
- '''
- 其他出库单生成出库凭证
- 借:如果出库类型为盘亏,取科目 1901 待处理财产损益;如果为其他,取核算类别的会计科目
- 贷:库存商品(商品分类上会计科目)
- '''
- voucher = self.env['voucher'].create({'date': self.date
- })
- credit_sum = 0 # 贷方之和
- for line in self.line_out_ids:
- if line.cost: # 贷方行(多行)
- self.env['voucher.line'].create({
- 'name': '%s %s' % (self.name, self.note or ''),
- 'account_id': line.goods_id.category_id.account_id.id,
- 'credit': line.cost,
- 'voucher_id': voucher.id,
- 'goods_id': line.goods_id.id,
- 'goods_qty': line.goods_qty,
- })
- credit_sum += line.cost
- account = self.type == 'inventory' \
- and self.env.ref('finance.small_business_chart1901') \
- or self.finance_category_id.account_id
- if credit_sum: # 借方行(汇总一行)
- self.env['voucher.line'].create({
- 'name': '%s %s' % (self.name, self.note or ''),
- 'account_id': account.id,
- 'auxiliary_id': self.auxiliary_id.id,
- 'debit': credit_sum,
- 'voucher_id': voucher.id,
- })
- if len(voucher.line_ids) > 0:
- voucher.voucher_done()
- return voucher
- else:
- voucher.unlink()
-
- def delete_voucher(self):
- # 反审核其他出库单时删除对应的出库凭证
- voucher = self.voucher_id
- if voucher.state == 'done':
- voucher.voucher_draft()
-
- voucher.unlink()
-
- def on_barcode_scanned(self, barcode):
- self.move_id.scan_barcode(self._name, barcode, self._origin.id)
-
- def action_batch_split(self):
- """其他出库单 按批次先进先出原则 批量拆分各批次商品 行"""
- for line_out in self.line_out_ids:
- res = line_out.env['wh.move.line'].search([ # 按商品去找出这个商品的所有批次数
- ('goods_id', '=', line_out.goods_id.id),
- ('state', '=', 'done'),
- ('lot', '!=', False),
- ('qty_remaining', '>', 0),
- ('warehouse_dest_id', '=', self.warehouse_id.id),
- ], order='lot asc, qty_remaining asc')
- if len(res):
- """
- 第一步:先把当前大于1的商品数量记下来
- 第二步:把这个商品行删除掉
- 第三步:按批次去拆分第一步记下来的数量
- """
- # 第一步:先把当前大于1的商品数量记下来
- wh_obj = line_out.env['wh.move.line'].search([
- ('goods_id', '=', line_out.goods_id.id),
- ('move_id', '=', line_out.move_id.id),
- ])
- v = sum(lin.goods_qty for lin in wh_obj)
-
- # 第二步:把这个商品行删除掉
- sql = """delete from wh_move_line where goods_id = '{}' and move_id = '{}'
- """.format(line_out.goods_id.id, line_out.move_id.id)
- self._cr.execute(sql)
-
- # 第三步:按批次去拆分第一步记下来的数量
- for line in res:
- if v <= 0:
- continue
- if v >= line.qty_remaining:
- vals = {
- 'move_id': line_out.move_id.id,
- 'goods_id': line_out.goods_id.id,
- 'lot': line.lot,
- 'lot_id': line.id,
- 'goods_qty': line.qty_remaining,
- 'type': 'out',
- 'cost_unit': line.cost_unit,
- 'cost': line.cost,
- 'expiration_date': line.expiration_date,
- }
- line_out.env['wh.move.line'].create(vals)
- v -= line.qty_remaining
- else:
- vals = {
- 'move_id': line_out.move_id.id,
- 'goods_id': line_out.goods_id.id,
- 'lot': line.lot,
- 'lot_id': line.id,
- 'goods_qty': v,
- 'type': 'out',
- 'cost_unit': line.cost_unit,
- 'cost': line.cost,
- 'expiration_date': line.expiration_date,
- }
- line_out.env['wh.move.line'].create(vals)
- v -= line.qty_remaining
-
-
- class WhIn(models.Model):
- _name = 'wh.in'
- _description = '其他入库单'
- _inherit = ['mail.thread']
- _order = 'date DESC, id DESC'
-
- _inherits = {
- 'wh.move': 'move_id',
- }
-
- TYPE_SELECTION = [
- ('inventory', '盘盈'),
- ('others', '其他入库'),
- ]
-
- move_id = fields.Many2one('wh.move', '移库单', required=True, index=True, ondelete='cascade',
- help='其他入库单对应的移库单')
- type = fields.Selection(TYPE_SELECTION, '业务类别', default='others',
- help='类别: 盘盈,其他入库,初始')
- amount_total = fields.Float(compute='_get_amount_total', string='合计成本金额',
- store=True, readonly=True, digits='Amount',
- help='该入库单的入库金额总和')
- voucher_id = fields.Many2one('voucher', '入库凭证',
- readonly=True,
- help='该入库单确认后生成的入库凭证')
- is_init = fields.Boolean('初始化单')
-
- @inherits()
- def approve_order(self):
- for order in self:
- if order.state == 'done':
- raise UserError('请不要重复入库')
- voucher = order.create_voucher()
- order.write({
- 'voucher_id': voucher and voucher[0] and voucher[0].id,
- 'state': 'done',
- })
- return True
-
- @inherits()
- def cancel_approved_order(self):
- for order in self:
- if order.state == 'draft':
- raise UserError('请不要重复撤销 %s' % self._description)
- order.delete_voucher()
- order.state = 'draft'
- return True
-
- @inherits()
- def unlink(self):
- for order in self:
- return order.move_id.unlink()
-
- @api.depends('line_in_ids.cost')
- def _get_amount_total(self):
- self.amount_total = sum(line.cost for line in self.line_in_ids)
-
- def get_move_origin(self, vals):
- return self._name + '.' + vals.get('type')
-
- @api.model
- @create_name
- @create_origin
- def create(self, vals):
- return super(WhIn, self).create(vals)
-
- @api.onchange('type')
- def onchange_type(self):
- self.warehouse_id = self.env['warehouse'].get_warehouse_by_type(
- self.type).id
-
- def create_voucher(self):
- # 入库单生成入库凭证
- '''
- 借:商品分类对应的会计科目 一般是库存商品
- 贷:如果入库类型为盘盈,取科目 1901 待处理财产损益(暂时写死)
- 如果入库类型为其他,取收发类别的会计科目
- '''
-
- # 初始化单的话,先找是否有初始化凭证,没有则新建一个
- if self.is_init:
- vouch_id = self.env['voucher'].search([('is_init', '=', True)])
- if not vouch_id:
- vouch_id = self.env['voucher'].create({'date': self.date,
- 'is_init': True
- })
- else:
- vouch_id = self.env['voucher'].create({'date': self.date
- })
- debit_sum = 0
- for line in self.line_in_ids:
- init_obj = self.is_init and 'init_warehouse - %s' % (self.id) or ''
- if line.cost:
- self.env['voucher.line'].create({
- 'name': '%s %s' % (self.name, self.note or ''),
- 'account_id': line.goods_id.category_id.account_id.id,
- 'debit': line.cost,
- 'voucher_id': vouch_id.id,
- 'goods_id': line.goods_id.id,
- 'goods_qty': line.goods_qty,
- 'init_obj': init_obj,
- })
- debit_sum += line.cost
-
- # 贷方科目: 如果是盘盈则取主营业务成本,否则取收发类别上的科目
- account = self.type == 'inventory' \
- and self.env.ref('finance.small_business_chart1901') \
- or self.finance_category_id.account_id
-
- if not self.is_init:
- if debit_sum:
- self.env['voucher.line'].create({
- 'name': '%s %s' % (self.name, self.note or ''),
- 'account_id': account.id,
- 'auxiliary_id': self.auxiliary_id.id,
- 'credit': debit_sum,
- 'voucher_id': vouch_id.id,
- })
- if not self.is_init:
- if len(vouch_id.line_ids) > 0:
- vouch_id.voucher_done()
- return vouch_id
- else:
- vouch_id.unlink()
- else:
- return vouch_id
-
- def delete_voucher(self):
- # 反审核入库单时删除对应的入库凭证
- if self.voucher_id:
- if self.voucher_id.state == 'done':
- self.voucher_id.voucher_draft()
- voucher = self.voucher_id
- # 始初化单反审核只删除明细行
- if self.is_init:
- vouch_obj = self.env['voucher'].search(
- [('id', '=', voucher.id)])
- vouch_obj_lines = self.env['voucher.line'].search([
- ('voucher_id', '=', vouch_obj.id),
- ('goods_id', 'in', [
- line.goods_id.id for line in self.line_in_ids]),
- ('init_obj', '=', 'init_warehouse - %s' % (self.id)), ])
- for vouch_obj_line in vouch_obj_lines:
- vouch_obj_line.unlink()
- else:
- voucher.unlink()
-
-
- class WhInternal(models.Model):
- _name = 'wh.internal'
- _description = '内部调拨单'
- _inherit = ['mail.thread']
- _order = 'date DESC, id DESC'
-
- _inherits = {
- 'wh.move': 'move_id',
- }
-
- move_id = fields.Many2one('wh.move', '移库单', required=True, index=True, ondelete='cascade',
- help='调拨单对应的移库单')
- amount_total = fields.Float(compute='_get_amount_total', string='合计成本金额',
- store=True, readonly=True, digits='Amount',
- help='该调拨单的出库金额总和')
-
- def goods_inventory(self, vals):
- """
- 审核时若仓库中商品不足,则产生补货向导生成其他入库单并审核。
- :param vals: 创建其他入库单需要的字段及取值信息构成的字典
- :return:
- """
- auto_in = self.env['wh.in'].create(vals)
- self.with_context({'wh_in_line_ids': [line.id for line in
- auto_in.line_in_ids]}).approve_order()
-
- @inherits_after()
- def approve_order(self):
- for order in self:
- if order.state == 'done':
- raise UserError('请不要重复入库')
- if self.env.user.company_id.is_enable_negative_stock: # 移库单检查负库存
- result_vals = self.env['wh.move'].create_zero_wh_in(
- self, self._name)
- if result_vals:
- return result_vals
- order.state = 'done'
- return True
-
- @inherits()
- def cancel_approved_order(self):
- for order in self:
- if order.state == 'draft':
- raise UserError('请不要重复撤销 %s' % self._description)
- order.state = 'draft'
- return True
-
- @inherits()
- def unlink(self):
- for order in self:
- return order.move_id.unlink()
-
- @api.depends('line_out_ids.cost')
- def _get_amount_total(self):
- self.amount_total = sum(line.cost for line in self.line_out_ids)
-
- @api.model
- @create_name
- @create_origin
- def create(self, vals):
- return super(WhInternal, self).create(vals)
|