[IMP] sale_order_batch: add cancel and set to open
This commit is contained in:
parent
426d617446
commit
8af3f6be79
9 changed files with 166 additions and 12 deletions
|
|
@ -1 +1,2 @@
|
||||||
from . import models
|
from . import models
|
||||||
|
from . import wizard
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,14 @@
|
||||||
"version": "16.0.2.3.0",
|
"version": "16.0.2.3.0",
|
||||||
"depends": ["sale", "product"],
|
"depends": ["sale", "product"],
|
||||||
"data": [
|
"data": [
|
||||||
"data/ir_sequence_data.xml",
|
"security/ir.model.access.csv",
|
||||||
|
"security/ir_rules.xml",
|
||||||
"views/sale_order_batch_views.xml",
|
"views/sale_order_batch_views.xml",
|
||||||
"views/sale_order_batch_product_views.xml",
|
"views/sale_order_batch_product_views.xml",
|
||||||
"views/sale_order_views.xml",
|
"views/sale_order_views.xml",
|
||||||
"views/sale_menus.xml",
|
"views/sale_menus.xml",
|
||||||
"security/ir.model.access.csv",
|
"wizard/sale_order_batch_cancel_wizard.xml",
|
||||||
"security/ir_rules.xml",
|
"data/ir_sequence_data.xml",
|
||||||
],
|
],
|
||||||
"license": "LGPL-3",
|
"license": "LGPL-3",
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@ class SaleOrder(models.Model):
|
||||||
check_company=True,
|
check_company=True,
|
||||||
domain="[('state','!=','closed')]",
|
domain="[('state','!=','closed')]",
|
||||||
)
|
)
|
||||||
|
batch_state = fields.Selection(
|
||||||
|
related="batch_id.state",
|
||||||
|
string="Batch State",
|
||||||
|
)
|
||||||
|
|
||||||
def _get_current_batch(self):
|
def _get_current_batch(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from odoo import _, api, fields, models
|
from odoo import _, api, fields, models
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
from odoo.addons.sale.models.sale_order import INVOICE_STATUS
|
from odoo.addons.sale.models.sale_order import INVOICE_STATUS
|
||||||
|
|
||||||
|
|
@ -185,13 +186,37 @@ class SaleOrderBatch(models.Model):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_cancel(self):
|
def action_cancel(self):
|
||||||
for batch in self:
|
cancel_warning = self._show_cancel_wizard()
|
||||||
orders = batch.sale_order_ids
|
if cancel_warning:
|
||||||
|
self.ensure_one()
|
||||||
|
return {
|
||||||
|
"name": _("Cancel %s", self.name),
|
||||||
|
"view_mode": "form",
|
||||||
|
"type": "ir.actions.act_window",
|
||||||
|
"res_model": "sale.order.batch.cancel.wizard",
|
||||||
|
"target": "new",
|
||||||
|
"context": {"active_ids": self.ids},
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
self._action_cancel()
|
||||||
|
|
||||||
|
def _action_cancel(self):
|
||||||
|
orders = self.mapped("sale_order_ids")
|
||||||
# use _action_cancel to skip the wizzard
|
# use _action_cancel to skip the wizzard
|
||||||
# ToDo: Implement wizard logic
|
|
||||||
orders._action_cancel()
|
orders._action_cancel()
|
||||||
batch.update({"state": "cancel"})
|
self.write({"state": "cancel"})
|
||||||
return True
|
|
||||||
|
def _show_cancel_wizard(self):
|
||||||
|
"""Decide whether the sale.order.batch.cancel wizard should be shown to cancel specified orders.
|
||||||
|
|
||||||
|
:return: True if there is any non-draft order in the given orders
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.env.context.get("disable_cancel_warning"):
|
||||||
|
return False
|
||||||
|
batch_orders = self.mapped("sale_order_ids")
|
||||||
|
return any(order._show_cancel_wizard() for order in batch_orders)
|
||||||
|
|
||||||
def action_open(self):
|
def action_open(self):
|
||||||
for batch in self:
|
for batch in self:
|
||||||
|
|
@ -210,3 +235,29 @@ class SaleOrderBatch(models.Model):
|
||||||
"sale.order.batch"
|
"sale.order.batch"
|
||||||
) or _("New")
|
) or _("New")
|
||||||
return super().create(vals_list)
|
return super().create(vals_list)
|
||||||
|
|
||||||
|
|
||||||
|
class SaleOrderBatchCancelWizard(models.TransientModel):
|
||||||
|
_name = "sale.order.batch.cancel.wizard"
|
||||||
|
_description = "Sale Order Batch Cancel Wizard"
|
||||||
|
|
||||||
|
def action_cancel(self):
|
||||||
|
batches = self.env["sale.order.batch"].browse(self._context["active_ids"])
|
||||||
|
for batch in batches:
|
||||||
|
orders = batch.sale_order_ids
|
||||||
|
# Warn if any sale order is not in draft
|
||||||
|
not_draft_orders = orders.filtered(lambda o: o.state != "draft")
|
||||||
|
if not_draft_orders:
|
||||||
|
raise UserError(
|
||||||
|
_(
|
||||||
|
"You can only cancel batches where all sale orders are in draft state."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# use _action_cancel to skip the wizzard
|
||||||
|
# ToDo: Implement wizard logic
|
||||||
|
orders._action_cancel()
|
||||||
|
batch.update({"state": "cancel"})
|
||||||
|
return True
|
||||||
|
|
||||||
|
def action_discard(self):
|
||||||
|
return {"type": "ir.actions.act_window_close"}
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ access_sale_order_batch_invoicing_payments,sale.order.batch,model_sale_order_bat
|
||||||
access_sale_order_batch,sale.order.batch,model_sale_order_batch,sales_team.group_sale_salesman,1,1,1,0
|
access_sale_order_batch,sale.order.batch,model_sale_order_batch,sales_team.group_sale_salesman,1,1,1,0
|
||||||
access_sale_order_batch_manager,sale.order.batch.manager,model_sale_order_batch,sales_team.group_sale_manager,1,1,1,1
|
access_sale_order_batch_manager,sale.order.batch.manager,model_sale_order_batch,sales_team.group_sale_manager,1,1,1,1
|
||||||
access_sale_order_batch_product,sale.order.batch.product,model_sale_order_batch_product,sales_team.group_sale_salesman,1,1,1,1
|
access_sale_order_batch_product,sale.order.batch.product,model_sale_order_batch_product,sales_team.group_sale_salesman,1,1,1,1
|
||||||
|
sale_order_batch.access_sale_order_batch_cancel_wizard,access_sale_order_batch_cancel_wizard,sale_order_batch.model_sale_order_batch_cancel_wizard,base.group_user,1,1,1,1
|
||||||
|
|
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
<field name="company_id" groups="base.group_multi_company" optional="show" readonly="1"/>
|
<field name="company_id" groups="base.group_multi_company" optional="show" readonly="1"/>
|
||||||
<field name="company_id" groups="!base.group_multi_company" invisible="1"/>
|
<field name="company_id" groups="!base.group_multi_company" invisible="1"/>
|
||||||
<field name="sale_order_ids" widget="many2many_tags"/>
|
<field name="sale_order_ids" widget="many2many_tags"/>
|
||||||
|
<field
|
||||||
|
name="state"
|
||||||
|
decoration-success="state == 'sale' or state == 'done'"
|
||||||
|
decoration-info="state == 'draft' or state == 'sent'"
|
||||||
|
widget="badge"
|
||||||
|
optional="hide"
|
||||||
|
/>
|
||||||
<field
|
<field
|
||||||
name="invoice_status"
|
name="invoice_status"
|
||||||
decoration-success="invoice_status == 'invoiced'"
|
decoration-success="invoice_status == 'invoiced'"
|
||||||
|
|
@ -18,7 +25,27 @@
|
||||||
widget="badge"
|
widget="badge"
|
||||||
optional="show"
|
optional="show"
|
||||||
/>
|
/>
|
||||||
<field name="state"/>
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_order_batch_quotation_tree" model="ir.ui.view">
|
||||||
|
<field name="name">sale.order.batch.quotation.tree</field>
|
||||||
|
<field name="model">sale.order.batch</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="date_order"/>
|
||||||
|
<field name="company_id" groups="base.group_multi_company" optional="show" readonly="1"/>
|
||||||
|
<field name="company_id" groups="!base.group_multi_company" invisible="1"/>
|
||||||
|
<field name="sale_order_ids" widget="many2many_tags"/>
|
||||||
|
<field
|
||||||
|
name="state"
|
||||||
|
decoration-success="state == 'sale' or state == 'done'"
|
||||||
|
decoration-info="state == 'draft' or state == 'sent'"
|
||||||
|
widget="badge"
|
||||||
|
optional="show"
|
||||||
|
/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
@ -140,6 +167,7 @@
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Sale Orders" name="orders">
|
<page string="Sale Orders" name="orders">
|
||||||
|
<field name="state" invisible="1"/>
|
||||||
<field name="sale_order_ids">
|
<field name="sale_order_ids">
|
||||||
<tree delete="0" editable="0" create="0">
|
<tree delete="0" editable="0" create="0">
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
|
|
@ -148,13 +176,20 @@
|
||||||
<field name="amount_untaxed"/>
|
<field name="amount_untaxed"/>
|
||||||
<field name="amount_total"/>
|
<field name="amount_total"/>
|
||||||
<field name="company_id" invisible="1"/>
|
<field name="company_id" invisible="1"/>
|
||||||
|
<field
|
||||||
|
name="state"
|
||||||
|
decoration-success="state == 'sale' or state == 'done'"
|
||||||
|
decoration-info="state == 'draft' or state == 'sent'"
|
||||||
|
widget="badge"
|
||||||
|
optional="show"
|
||||||
|
/>
|
||||||
<field
|
<field
|
||||||
name="invoice_status"
|
name="invoice_status"
|
||||||
decoration-success="invoice_status == 'invoiced'"
|
decoration-success="invoice_status == 'invoiced'"
|
||||||
decoration-info="invoice_status == 'to invoice'"
|
decoration-info="invoice_status == 'to invoice'"
|
||||||
decoration-warning="invoice_status == 'upselling'"
|
decoration-warning="invoice_status == 'upselling'"
|
||||||
widget="badge"
|
widget="badge"
|
||||||
optional="show"
|
optional="hide"
|
||||||
/>
|
/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
|
|
@ -214,6 +249,7 @@
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
<field name="res_model">sale.order.batch</field>
|
<field name="res_model">sale.order.batch</field>
|
||||||
<field name="view_mode">tree,form,activity</field>
|
<field name="view_mode">tree,form,activity</field>
|
||||||
|
<field name="view_id" ref="view_order_batch_quotation_tree"/>
|
||||||
<field name="context">{'search_default_filter_batch_open': 1}</field>
|
<field name="context">{'search_default_filter_batch_open': 1}</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
@ -222,6 +258,7 @@
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
<field name="res_model">sale.order.batch</field>
|
<field name="res_model">sale.order.batch</field>
|
||||||
<field name="view_mode">tree,form,activity</field>
|
<field name="view_mode">tree,form,activity</field>
|
||||||
|
<field name="view_id" ref="view_order_batch_tree"/>
|
||||||
<field name="context">{'search_default_filter_batch_finished': 1}</field>
|
<field name="context">{'search_default_filter_batch_finished': 1}</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
|
||||||
1
sale_order_batch/wizard/__init__.py
Normal file
1
sale_order_batch/wizard/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import sale_order_batch_cancel_wizard
|
||||||
34
sale_order_batch/wizard/sale_order_batch_cancel_wizard.py
Normal file
34
sale_order_batch/wizard/sale_order_batch_cancel_wizard.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class SaleOrderBatchCancelWizard(models.TransientModel):
|
||||||
|
_name = "sale.order.batch.cancel.wizard"
|
||||||
|
_description = "Cancel Sale Order Batch Confirmation"
|
||||||
|
|
||||||
|
batch_ids = fields.Many2many(
|
||||||
|
comodel_name="sale.order.batch",
|
||||||
|
string="Batches to Cancel",
|
||||||
|
default=lambda self: self.env["sale.order.batch"].browse(
|
||||||
|
self.env.context.get("active_ids", [])
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
order_ids = fields.Many2many(
|
||||||
|
comodel_name="sale.order",
|
||||||
|
string="Orders to Cancel",
|
||||||
|
compute="_compute_order_ids",
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends("batch_ids")
|
||||||
|
def _compute_order_ids(self):
|
||||||
|
for record in self:
|
||||||
|
batches = record.batch_ids
|
||||||
|
record.order_ids = batches.mapped("sale_order_ids")
|
||||||
|
|
||||||
|
def action_cancel(self):
|
||||||
|
batches = self.batch_ids
|
||||||
|
batches._action_cancel()
|
||||||
|
return {"type": "ir.actions.act_window_close"}
|
||||||
|
|
||||||
|
def action_discard(self):
|
||||||
|
return {"type": "ir.actions.act_window_close"}
|
||||||
24
sale_order_batch/wizard/sale_order_batch_cancel_wizard.xml
Normal file
24
sale_order_batch/wizard/sale_order_batch_cancel_wizard.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<odoo>
|
||||||
|
<record id="view_sale_order_batch_cancel_wizard_form" model="ir.ui.view">
|
||||||
|
<field name="name">sale.order.batch.cancel.wizard.form</field>
|
||||||
|
<field name="model">sale.order.batch.cancel.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<group col="1">
|
||||||
|
<div col="2" class="alert alert-warning" role="alert">
|
||||||
|
<span>Are you sure you want to cancel this order?</span>
|
||||||
|
</div>
|
||||||
|
<group col="2">
|
||||||
|
<field name="batch_ids" invisible="1"/>
|
||||||
|
<field name="order_ids" widget="many2many_tags"/>
|
||||||
|
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button string="Cancel" name="action_cancel" type="object" class="btn-primary mx-1"/>
|
||||||
|
<button string="Discard" class="btn-secondary" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
Loading…
Reference in a new issue