GoodERP
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

146 lines
6.2KB

  1. # -*- coding: utf-8 -*-
  2. from odoo import _
  3. from datetime import date
  4. from odoo import models, fields, api
  5. from odoo.exceptions import UserError
  6. class SellReceiptWizard(models.TransientModel):
  7. _name = 'sell.receipt.wizard'
  8. _description = '销售收款一览表向导'
  9. @api.model
  10. def _default_date_start(self):
  11. return self.env.user.company_id.start_date
  12. @api.model
  13. def _default_date_end(self):
  14. return date.today()
  15. date_start = fields.Date('开始日期', default=_default_date_start,
  16. help='报表汇总的开始日期,默认为公司启用日期')
  17. date_end = fields.Date('结束日期', default=_default_date_end,
  18. help='报表汇总的结束日期,默认为当前日期')
  19. c_category_id = fields.Many2one('core.category', '客户类别',
  20. domain=[('type', '=', 'customer')],
  21. context={'type': 'customer'},
  22. help='只统计选定的客户类别')
  23. partner_id = fields.Many2one('partner', '客户',
  24. help='只统计选定的客户')
  25. user_id = fields.Many2one('res.users', '销售员',
  26. help='只统计选定的销售员')
  27. warehouse_id = fields.Many2one('warehouse', '仓库',
  28. help='只统计选定的仓库')
  29. company_id = fields.Many2one(
  30. 'res.company',
  31. string='公司',
  32. change_default=True,
  33. default=lambda self: self.env.company)
  34. def _get_domain(self):
  35. '''返回wizard界面上条件'''
  36. cond = [('date', '>=', self.date_start),
  37. ('date', '<=', self.date_end),
  38. ('state', '=', 'done')]
  39. if self.c_category_id:
  40. cond.append(
  41. ('partner_id.c_category_id', '=', self.c_category_id.id)
  42. )
  43. if self.partner_id:
  44. cond.append(('partner_id', '=', self.partner_id.id))
  45. if self.user_id:
  46. cond.append(('user_id', '=', self.user_id.id))
  47. if self.warehouse_id:
  48. cond += ['|', ('warehouse_id', '=', self.warehouse_id.id),
  49. ('warehouse_dest_id', '=', self.warehouse_id.id)]
  50. return cond
  51. def _compute_receipt(self, delivery):
  52. '''计算该发货单的已收款'''
  53. invoices = self.env['money.invoice'].search([
  54. ('name', '=', delivery.name),
  55. ('state', '=', 'done')])
  56. receipt = sum([invoice.reconciled for invoice in invoices])
  57. return receipt
  58. def _prepare_sell_receipt(self, delivery):
  59. '''对于传入的发货单/退货单,为创建销售收款一览表准备数据'''
  60. self.ensure_one()
  61. factor = delivery.is_return and -1 or 1 # 如果是退货则金额均取反
  62. sell_amount = factor * (delivery.discount_amount + delivery.amount)
  63. discount_amount = factor * delivery.discount_amount
  64. amount = factor * delivery.amount
  65. partner_cost = factor * delivery.partner_cost
  66. order_type = not delivery.is_return and '普通销售' or '销售退回'
  67. warehouse = not delivery.is_return and delivery.warehouse_id or delivery.warehouse_dest_id
  68. # 计算该发货单的已收款
  69. receipt = self._compute_receipt(delivery)
  70. # 计算回款率
  71. receipt_rate = (amount + partner_cost) != 0 and (receipt /
  72. (amount + partner_cost)) * 100 or 0
  73. return {
  74. 'c_category_id': delivery.partner_id.c_category_id.id,
  75. 'partner_id': delivery.partner_id.id,
  76. 'user_id': delivery.user_id.id,
  77. 'type': order_type,
  78. 'date': delivery.date,
  79. 'order_name': delivery.name,
  80. 'warehouse_id': warehouse.id,
  81. 'sell_amount': sell_amount,
  82. 'discount_amount': discount_amount,
  83. 'amount': amount,
  84. 'partner_cost': partner_cost,
  85. 'receipt': receipt,
  86. 'balance': amount + partner_cost - receipt,
  87. 'receipt_rate': receipt_rate,
  88. 'note': delivery.note,
  89. }
  90. def compute_partner_receipt(self, partner):
  91. """该客户所有收款单未核销金额合计数"""
  92. orders = self.env['money.order'].search([
  93. ('state', '=', 'done'),
  94. ('partner_id', '=', partner.id)])
  95. sum_amount = sum(order.to_reconcile for order in orders)
  96. return sum_amount
  97. def button_ok(self):
  98. self.ensure_one()
  99. res = []
  100. dict_part = {}
  101. if self.date_end < self.date_start:
  102. raise UserError(_('开始日期不能大于结束日期!\n 所选的开始日期:%s 结束日期:%s') %
  103. (self.date_start, self.date_end))
  104. delivery_obj = self.env['sell.delivery']
  105. for delivery in delivery_obj.search(self._get_domain(), order='partner_id'):
  106. if delivery.partner_id not in dict_part:
  107. dict_part[delivery.partner_id] = delivery
  108. else:
  109. dict_part[delivery.partner_id] += delivery
  110. for partner, deliverys in dict_part.items():
  111. for delivery in deliverys:
  112. # 用查找到的发货单信息来创建一览表
  113. line = self.env['sell.receipt'].create(
  114. self._prepare_sell_receipt(delivery))
  115. res.append(line.id)
  116. # 增加一行,编号是未核销预收款,已收款是该客户所有收款单未核销金额合计数,应收款余额为负的预收款
  117. summary_line = self.env['sell.receipt'].create({
  118. 'partner_id': partner.id,
  119. 'order_name': '未核销预收款',
  120. 'receipt': self.compute_partner_receipt(partner),
  121. 'balance': -self.compute_partner_receipt(partner),
  122. })
  123. res.append(summary_line.id)
  124. return {
  125. 'name': _('销售收款一览表'),
  126. 'view_mode': 'list',
  127. 'res_model': 'sell.receipt',
  128. 'type': 'ir.actions.act_window',
  129. 'target': 'main',
  130. 'domain': [('id', 'in', res)],
  131. 'limit': 65535,
  132. }
上海开阖软件有限公司 沪ICP备12045867号-1