|
-
- from datetime import date
- from odoo import models, fields, api
- from odoo.exceptions import UserError
-
-
- class SellReceiptWizard(models.TransientModel):
- _name = 'sell.receipt.wizard'
- _description = '销售收款一览表向导'
-
- @api.model
- def _default_date_start(self):
- return self.env.user.company_id.start_date
-
- @api.model
- def _default_date_end(self):
- return date.today()
-
- date_start = fields.Date('开始日期', default=_default_date_start,
- help='报表汇总的开始日期,默认为公司启用日期')
- date_end = fields.Date('结束日期', default=_default_date_end,
- help='报表汇总的结束日期,默认为当前日期')
- c_category_id = fields.Many2one('core.category', '客户类别',
- domain=[('type', '=', 'customer')],
- context={'type': 'customer'},
- help='只统计选定的客户类别')
- partner_id = fields.Many2one('partner', '客户',
- help='只统计选定的客户')
- user_id = fields.Many2one('res.users', '销售员',
- help='只统计选定的销售员')
- warehouse_id = fields.Many2one('warehouse', '仓库',
- help='只统计选定的仓库')
- company_id = fields.Many2one(
- 'res.company',
- string='公司',
- change_default=True,
- default=lambda self: self.env.company)
-
- def _get_domain(self):
- '''返回wizard界面上条件'''
- cond = [('date', '>=', self.date_start),
- ('date', '<=', self.date_end),
- ('state', '=', 'done')]
- if self.c_category_id:
- cond.append(
- ('partner_id.c_category_id', '=', self.c_category_id.id)
- )
- if self.partner_id:
- cond.append(('partner_id', '=', self.partner_id.id))
- if self.user_id:
- cond.append(('user_id', '=', self.user_id.id))
- if self.warehouse_id:
- cond += ['|', ('warehouse_id', '=', self.warehouse_id.id),
- ('warehouse_dest_id', '=', self.warehouse_id.id)]
- return cond
-
- def _compute_receipt(self, delivery):
- '''计算该发货单的已收款'''
- invoices = self.env['money.invoice'].search([
- ('name', '=', delivery.name),
- ('state', '=', 'done')])
- receipt = sum([invoice.reconciled for invoice in invoices])
- return receipt
-
- def _prepare_sell_receipt(self, delivery):
- '''对于传入的发货单/退货单,为创建销售收款一览表准备数据'''
- self.ensure_one()
- factor = delivery.is_return and -1 or 1 # 如果是退货则金额均取反
- sell_amount = factor * (delivery.discount_amount + delivery.amount)
- discount_amount = factor * delivery.discount_amount
- amount = factor * delivery.amount
- partner_cost = factor * delivery.partner_cost
- order_type = not delivery.is_return and '普通销售' or '销售退回'
- warehouse = not delivery.is_return and delivery.warehouse_id or delivery.warehouse_dest_id
- # 计算该发货单的已收款
- receipt = self._compute_receipt(delivery)
- # 计算回款率
- receipt_rate = (amount + partner_cost) != 0 and (receipt /
- (amount + partner_cost)) * 100 or 0
- return {
- 'c_category_id': delivery.partner_id.c_category_id.id,
- 'partner_id': delivery.partner_id.id,
- 'user_id': delivery.user_id.id,
- 'type': order_type,
- 'date': delivery.date,
- 'order_name': delivery.name,
- 'warehouse_id': warehouse.id,
- 'sell_amount': sell_amount,
- 'discount_amount': discount_amount,
- 'amount': amount,
- 'partner_cost': partner_cost,
- 'receipt': receipt,
- 'balance': amount + partner_cost - receipt,
- 'receipt_rate': receipt_rate,
- 'note': delivery.note,
- }
-
- def compute_partner_receipt(self, partner):
- """该客户所有收款单未核销金额合计数"""
- orders = self.env['money.order'].search([
- ('state', '=', 'done'),
- ('partner_id', '=', partner.id)])
- sum_amount = sum(order.to_reconcile for order in orders)
- return sum_amount
-
- def button_ok(self):
- self.ensure_one()
- res = []
- dict_part = {}
- if self.date_end < self.date_start:
- raise UserError('开始日期不能大于结束日期!\n 所选的开始日期:%s 结束日期:%s' %
- (self.date_start, self.date_end))
-
- delivery_obj = self.env['sell.delivery']
- for delivery in delivery_obj.search(self._get_domain(), order='partner_id'):
- if delivery.partner_id not in dict_part:
- dict_part[delivery.partner_id] = delivery
- else:
- dict_part[delivery.partner_id] += delivery
- for partner, deliverys in dict_part.items():
- for delivery in deliverys:
- # 用查找到的发货单信息来创建一览表
- line = self.env['sell.receipt'].create(
- self._prepare_sell_receipt(delivery))
- res.append(line.id)
- # 增加一行,编号是未核销预收款,已收款是该客户所有收款单未核销金额合计数,应收款余额为负的预收款
- summary_line = self.env['sell.receipt'].create({
- 'partner_id': partner.id,
- 'order_name': '未核销预收款',
- 'receipt': self.compute_partner_receipt(partner),
- 'balance': -self.compute_partner_receipt(partner),
- })
- res.append(summary_line.id)
-
- return {
- 'name': '销售收款一览表',
- 'view_mode': 'list',
- 'res_model': 'sell.receipt',
- 'type': 'ir.actions.act_window',
- 'target': 'main',
- 'domain': [('id', 'in', res)],
- 'limit': 65535,
- }
|