优化销售订单逾期

This commit is contained in:
jinling.yang
2024-10-08 17:50:59 +08:00
parent ccd01c9c75
commit a00f4af923
8 changed files with 128 additions and 133 deletions

View File

@@ -16,7 +16,7 @@
'data/bussiness_node.xml', 'data/bussiness_node.xml',
'data/cron_data.xml', 'data/cron_data.xml',
'data/template_data.xml', 'data/template_data.xml',
'views/sf_message_sale_view.xml',
], ],
'test': [ 'test': [

View File

@@ -26,31 +26,31 @@
<field name="active" eval="True"/> <field name="active" eval="True"/>
</record> </record>
<record model="ir.cron" id="ir_cron_mrp_workorder_overdue_warning"> <!-- <record model="ir.cron" id="ir_cron_mrp_workorder_overdue_warning">-->
<field name="name">装夹预调工单逾期预警</field> <!-- <field name="name">装夹预调工单逾期预警</field>-->
<field name="model_id" ref="model_mrp_workorder"/> <!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<field name="state">code</field> <!-- <field name="state">code</field>-->
<field name="code">model._overdue_warning_func()</field> <!-- <field name="code">model._overdue_warning_func()</field>-->
<field name="interval_number">1</field> <!-- <field name="interval_number">1</field>-->
<field name="interval_type">minutes</field> <!-- <field name="interval_type">minutes</field>-->
<field name="numbercall">-1</field> <!-- <field name="numbercall">-1</field>-->
<field name="doall" eval="False"/> <!-- <field name="doall" eval="False"/>-->
<field name="user_id" ref="base.user_root"/> <!-- <field name="user_id" ref="base.user_root"/>-->
<field name="active" eval="True"/> <!-- <field name="active" eval="True"/>-->
</record> <!-- </record>-->
<record model="ir.cron" id="ir_cron_mrp_workorder_overdue"> <!-- <record model="ir.cron" id="ir_cron_mrp_workorder_overdue">-->
<field name="name">工单已逾期</field> <!-- <field name="name">工单已逾期</field>-->
<field name="model_id" ref="model_mrp_workorder"/> <!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<field name="state">code</field> <!-- <field name="state">code</field>-->
<field name="code">model._overdue_func()</field> <!-- <field name="code">model._overdue_func()</field>-->
<field name="interval_number">1</field> <!-- <field name="interval_number">1</field>-->
<field name="interval_type">minutes</field> <!-- <field name="interval_type">minutes</field>-->
<field name="numbercall">-1</field> <!-- <field name="numbercall">-1</field>-->
<field name="doall" eval="False"/> <!-- <field name="doall" eval="False"/>-->
<field name="user_id" ref="base.user_root"/> <!-- <field name="user_id" ref="base.user_root"/>-->
<field name="active" eval="True"/> <!-- <field name="active" eval="True"/>-->
</record> <!-- </record>-->
<!-- --> <!-- -->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_overdue_warning">--> <!-- <record model="ir.cron" id="ir_cron_mrp_workorder_overdue_warning">-->
<!-- <field name="name">工单逾期预警</field>--> <!-- <field name="name">工单逾期预警</field>-->

View File

@@ -22,9 +22,8 @@
<field name="bussiness_node_id" ref="bussiness_to_be_confirm"/> <field name="bussiness_node_id" ref="bussiness_to_be_confirm"/>
<field name="msgtype">markdown</field> <field name="msgtype">markdown</field>
<field name="urgency">normal</field> <field name="urgency">normal</field>
<field name="content">### 待排程提醒: <field name="content">### 销售订单逾期预警
单号:产品[{{product_id}}]({{url}}) 事项:共有{{sale_warning_num}}个销售订单有逾期风险
事项:{{mrp_production_count}}个制造订单待计划排程
</field> </field>
</record> </record>
@@ -36,8 +35,7 @@
<field name="msgtype">markdown</field> <field name="msgtype">markdown</field>
<field name="urgency">normal</field> <field name="urgency">normal</field>
<field name="content">### 待排程提醒: <field name="content">### 待排程提醒:
单号:销售订单[{{names}}]({{url}}) 事项:共有{{sale_overdue_num}}个销售订单已逾期
事项:共有{{production_count}}个制造订单未加工完成,订单有逾期风险
</field> </field>
</record> </record>

View File

@@ -7,8 +7,6 @@ class SFMessageSale(models.Model):
_name = 'sale.order' _name = 'sale.order'
_inherit = ['sale.order', 'jikimo.message.dispatch'] _inherit = ['sale.order', 'jikimo.message.dispatch']
delivery_warning = fields.Selection([('normal', '正常'), ('warning', '告警'), ('overdue', '逾期')], string='时效')
def create(self, vals_list): def create(self, vals_list):
res = super(SFMessageSale, self).create(vals_list) res = super(SFMessageSale, self).create(vals_list)
if res: if res:
@@ -45,8 +43,8 @@ class SFMessageSale(models.Model):
def _get_message(self, message_queue_ids): def _get_message(self, message_queue_ids):
contents = [] contents = []
url = self.env['ir.config_parameter'].get_param('web.base.url') url = self.env['ir.config_parameter'].get_param('web.base.url')
i = 0
for item in message_queue_ids: for item in message_queue_ids:
i = 0
# 待接单的处理 # 待接单的处理
if item.message_template_id.bussiness_node_id.name == '待接单': if item.message_template_id.bussiness_node_id.name == '待接单':
content = super(SFMessageSale, self)._get_message(item) content = super(SFMessageSale, self)._get_message(item)
@@ -66,30 +64,71 @@ class SFMessageSale(models.Model):
content = content[0].replace('{{product_id}}', product).replace('{{url}}', url) content = content[0].replace('{{product_id}}', product).replace('{{url}}', url)
contents.append(content) contents.append(content)
elif item.message_template_id.bussiness_node_id.name == '销售订单逾期预警': elif item.message_template_id.bussiness_node_id.name == '销售订单逾期预警':
sale_order_warning = self.sudo().search([('delivery_warning', '=', 'warning'),('id','=',int(item.res_id))]) current_time = datetime.now()
# if sale_order_warning: time_range = timedelta(minutes=2)
# i++ for reminder_time in item.message_template_id.reminder_time_ids:
# content = item.message_template_id.content
# if i>1 target_time = current_time.replace(hour=reminder_time, minute=0, second=0, microsecond=0)
if target_time - time_range <= current_time <= target_time + time_range:
print("当前时间在12点02分以内")
sale_order_warning = self.sudo().search(
[('delivery_warning', '=', 'warning'), ('id', '=', int(item.res_id))])
if sale_order_warning:
i += 1
if i >= 1:
content = content.replace('{{sale_warning_num}}', i).replace('{{url}}', url)
contents.append(content)
elif item.message_template_id.bussiness_node_id.name == '销售订单已逾期':
current_time = datetime.now()
time_range = timedelta(minutes=2)
for reminder_time in item.message_template_id.reminder_time_ids:
content = item.message_template_id.content
target_time = current_time.replace(hour=reminder_time, minute=0, second=0, microsecond=0)
if target_time - time_range <= current_time <= target_time + time_range:
print("当前时间在12点02分以内")
sale_order_overdue = self.sudo().search(
[('delivery_warning', '=', 'overdue'), ('id', '=', int(item.res_id))])
if sale_order_overdue:
i += 1
if i >= 1:
content = content.replace('{{sale_overdue_num}}', i).replace('{{url}}', url)
contents.append(content)
return contents return contents
# # 销售订单逾期预警 # # 销售订单逾期预警
def _overdue_warning_func(self): def _overdue_warning_func(self):
today = fields.Date.today() today = fields.Date.today()
deadline_check = today + timedelta(days=2) deadline_check = today + timedelta(days=2)
sale_order = self.sudo().search([('state', 'in', ['sale']), ('deadline_of_delivery', '!=', False)]) sale_order = self.sudo().search([('state', 'in', ['sale']), ('deadline_of_delivery', '!=', False)])
for item in sale_order: for item in sale_order:
if deadline_check < item.deadline_of_delivery: production = self.env['mrp.production'].search([('origin', '=', item.name)])
item.delivery_warning = '告警' if len(production.filtered(
else: lambda p: p.state not in ['done', 'scrap'])) != item.mrp_production_count:
item.delivery_warning = '正常' if deadline_check < item.deadline_of_delivery:
item.delivery_warning = 'warning'
elif len(production.filtered(
lambda p: p.state in ['done', 'scrap'])) == item.mrp_production_count:
if deadline_check < item.deadline_of_delivery and item.delivery_status == 'pending':
item.delivery_warning = 'warning'
sale_order_warning = self.sudo().search([('delivery_warning', '=', 'warning')]) sale_order_warning = self.sudo().search([('delivery_warning', '=', 'warning')])
if sale_order_warning: if sale_order_warning:
if
sale_order_warning.add_queue('销售订单逾期预警') sale_order_warning.add_queue('销售订单逾期预警')
# 销售订单已逾期 订单交期(交货日期)-当前日期时间≤0(未交货完成的销售订单)
# 销售订单已逾期
def _overdue_func(self): def _overdue_func(self):
return 1 today = fields.Date.today()
sale_order = self.sudo().search([('state', 'in', ['sale']), ('deadline_of_delivery', '!=', False)])
for item in sale_order:
delta = item.deadline_of_delivery - today
production = self.env['mrp.production'].search([('origin', '=', item.name)])
if len(production.filtered(
lambda p: p.state not in ['done', 'scrap'])) != item.mrp_production_count:
if delta <= timedelta(days=0):
item.delivery_warning = 'overdue'
elif len(production.filtered(
lambda p: p.state in ['done', 'scrap'])) == item.mrp_production_count:
if delta <= timedelta(days=0):
item.delivery_warning = 'overdue'
sale_order_overdue = self.sudo().search([('delivery_warning', '=', 'overdue')])
if sale_order_overdue:
sale_order_overdue.add_queue('销售订单已逾期')

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © <2016> <top hy>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>
<data>
</data>
</odoo>

View File

@@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © <2016> <top hy>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>
<data>
<record id="sf_message_template_view_form" model="ir.ui.view">
<field name="name">sf.message.template.view.form</field>
<field name="model">message.template</field>
<field name="arch" type="xml">
<form string="消息模板">
<sheet>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name" class="w-100" required="1"/>
</h1>
</div>
<group>
<!-- <field name="type"/>-->
<field name="notify_model_id"/>
<field name="content" widget="html" class="oe-bordered-editor"
options="{'style-inline': true, 'codeview': true, 'dynamic_placeholder': true}"/>
<field name="description"/>
<field name="msgtype"/>
<field name="notification_department_id"/>
<field name="notification_employee_ids" widget="many2many_tags"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="sf_message_template_view_tree" model="ir.ui.view">
<field name="name">sf.message.template.view.tree</field>
<field name="model">message.template</field>
<field name="arch" type="xml">
<tree string="消息模板">
<field name="name"/>
<!-- <field name="type"/>-->
<field name="content"/>
<field name="msgtype"/>
<field name="notification_department_id"/>
<field name="notification_employee_ids" widget="many2many_tags"/>
<field name="description"/>
</tree>
</field>
</record>
<record id="sf_message_template_search_view" model="ir.ui.view">
<field name="name">sf.message.template.search.view</field>
<field name="model">message.template</field>
<field name="arch" type="xml">
<search>
<field name="name" string="模糊搜索"
filter_domain="['|','|',('name','like',self),('description','like',self)]"/>
<field name="name"/>
<filter name="filter_active" string="已归档" domain="[('active','=',False)]"/>
</search>
</field>
</record>
<!--定义单证类型视图动作-->
<record id="sf_message_template_action" model="ir.actions.act_window">
<field name="name">消息模板</field>
<field name="res_model">message.template</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="sf_message_template_view_tree"/>
</record>
<menuitem id="msg_set_menu" name="消息设置" parent="base.menu_administration" sequence="1"/>
<menuitem id="sf_message_template_send_menu" name="消息模板" parent="msg_set_menu"
action="sf_message_template_action" sequence="1"/>
</data>
</odoo>

View File

@@ -55,6 +55,9 @@ class ReSaleOrder(models.Model):
store=True, readonly=False, copy=False, precompute=True, store=True, readonly=False, copy=False, precompute=True,
states=READONLY_FIELD_STATES, default=fields.Datetime.now) states=READONLY_FIELD_STATES, default=fields.Datetime.now)
delivery_warning = fields.Selection([('normal', '正常'), ('warning', '告警'), ('overdue', '逾期')], string='时效')
# 业务平台分配工厂后在智能工厂先创建销售订单 # 业务平台分配工厂后在智能工厂先创建销售订单
def sale_order_create(self, company_id, delivery_name, delivery_telephone, delivery_address, def sale_order_create(self, company_id, delivery_name, delivery_telephone, delivery_address,
deadline_of_delivery, payments_way, pay_way): deadline_of_delivery, payments_way, pay_way):

View File

@@ -67,7 +67,8 @@
<attribute name="attrs">{'readonly': [('state', 'in', ['cancel','sale'])]}</attribute> <attribute name="attrs">{'readonly': [('state', 'in', ['cancel','sale'])]}</attribute>
</field> </field>
<field name="payment_term_id" position="after"> <field name="payment_term_id" position="after">
<field name="deadline_of_delivery" attrs="{'readonly': [('state', 'in', ('sale','cancel'))]}"/> <field name="picking_ids"/>
<field name="deadline_of_delivery" />
<field name="payments_way" attrs="{'readonly': [('state', 'in', ('sale','cancel'))]}"/> <field name="payments_way" attrs="{'readonly': [('state', 'in', ('sale','cancel'))]}"/>
<field name="pay_way" attrs="{'readonly': [('state', 'in', ('sale','cancel'))]}"/> <field name="pay_way" attrs="{'readonly': [('state', 'in', ('sale','cancel'))]}"/>
<!-- <field name="schedule_status" readonly="1"/> --> <!-- <field name="schedule_status" readonly="1"/> -->
@@ -78,6 +79,7 @@
</xpath> </xpath>
<xpath expr="//field[@name='order_line']/tree/field[@name='price_subtotal']" position="after"> <xpath expr="//field[@name='order_line']/tree/field[@name='price_subtotal']" position="after">
<field name="remark"/> <field name="remark"/>
</xpath> </xpath>
<xpath expr="//field[@name='order_line']/tree/field[@name='product_template_id']" position="attributes"> <xpath expr="//field[@name='order_line']/tree/field[@name='product_template_id']" position="attributes">
<attribute name="options">{'no_create': True}</attribute> <attribute name="options">{'no_create': True}</attribute>
@@ -180,6 +182,20 @@
</field> </field>
</record> </record>
<record id="sale_order_view_search_inherit_sale_message" model="ir.ui.view">
<field name="name">sale.order.message.search.view</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.sale_order_view_search_inherit_sale"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<xpath expr="//filter[@name='upselling']" position="after">
<separator/>
<filter string="预警" name="filter_order_warning" domain="[('delivery_warning', '=', 'warning')]"/>
<filter string="逾期" name="filter_order_overdue" domain="[('delivery_warning', '=', 'overdue')]"/>
</xpath>
</field>
</record>
<record id="view_order_tree_inherit_sf" model="ir.ui.view"> <record id="view_order_tree_inherit_sf" model="ir.ui.view">
<field name="name">sale.order.tree</field> <field name="name">sale.order.tree</field>
<field name="model">sale.order</field> <field name="model">sale.order</field>
@@ -189,18 +205,15 @@
<!-- <attribute name="default_order">schedule_status desc,date_order asc</attribute> --> <!-- <attribute name="default_order">schedule_status desc,date_order asc</attribute> -->
<attribute name="default_order">create_date desc</attribute> <attribute name="default_order">create_date desc</attribute>
<attribute name="create">False</attribute> <attribute name="create">False</attribute>
<attribute name="decoration-warning">delivery_warning == 'warning'</attribute>
<attribute name="decoration-danger">delivery_warning == 'overdue'</attribute>
</tree> </tree>
<field name="name" position="attributes"> <field name="name" position="attributes">
<attribute name="string">订单号</attribute> <attribute name="string">订单号</attribute>
</field> </field>
<!-- <field name="amount_total" position="after"> --> <field name="amount_total" position="after">
<!-- <field name="schedule_status" widget="badge" --> <field name="delivery_warning" invisible="1"/>
<!-- decoration-success="schedule_status == 'received'" --> </field>
<!-- decoration-warning="schedule_status == 'to process'" -->
<!-- decoration-danger="schedule_status == 'to receive'" -->
<!-- decoration-muted="schedule_status == 'to process'" -->
<!-- decoration-info="schedule_status == 'to schedule'"/> -->
<!-- </field> -->
</field> </field>
</record> </record>
@@ -225,10 +238,18 @@
</field> </field>
</field> </field>
</record> </record>
<record id="sale.product_template_action" model="ir.actions.act_window"> <record id="sale.product_template_action" model="ir.actions.act_window">
<field name="context">{"search_default_categ_id":1, <field name="context">{"search_default_categ_id":1,
"search_default_filter_to_sell":1,"sale_multi_pricelist_product_template": 1} "search_default_filter_to_sell":1,"sale_multi_pricelist_product_template": 1}
</field> </field>
</record> </record>
<record id="sale.action_orders" model="ir.actions.act_window">
<field name="search_view_id" ref="sale_order_view_search_inherit_sale_message"/>
<field name="context">{ 'search_default_filter_order_warning':1,'search_default_filter_order_overdue':1}
</field>
</record>
</data> </data>
</odoo> </odoo>