Fix: Sale Order
This commit is contained in:
		
							
								
								
									
										170
									
								
								sale_order.py
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								sale_order.py
									
									
									
									
									
								
							| @@ -5,6 +5,7 @@ from trytond.pool import Pool | |||||||
| from trytond.transaction import Transaction | from trytond.transaction import Transaction | ||||||
| from trytond.modules.currency.fields import Monetary | from trytond.modules.currency.fields import Monetary | ||||||
| from trytond.modules.product import price_digits | from trytond.modules.product import price_digits | ||||||
|  | from trytond.pyson import Eval | ||||||
| from decimal import Decimal | from decimal import Decimal | ||||||
| from datetime import date | from datetime import date | ||||||
|  |  | ||||||
| @@ -13,63 +14,53 @@ class SaleOrder (Workflow, ModelView, ModelSQL): | |||||||
|     "Sale Order" |     "Sale Order" | ||||||
|     __name__ = 'sale.order' |     __name__ = 'sale.order' | ||||||
|  |  | ||||||
|  |     _states = { | ||||||
|  |         'readonly': Eval('state').in_(['confirmed']) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     company = fields.Many2One( |     company = fields.Many2One( | ||||||
|         'company.company', "Company", required=True |         'company.company', "Company", states={ | ||||||
|     ) |             'readonly': True, | ||||||
|     party = fields.Many2One( |             'required': True | ||||||
|         'party.party', "Party", required=True |         }) | ||||||
|     ) |  | ||||||
|     pickup_location = fields.Selection( |  | ||||||
|         [("on_site", "On Site"), |  | ||||||
|          ("at_home", "At Home")], 'Pickup Location' |  | ||||||
|     ) |  | ||||||
|     order_address = fields.Many2One( |  | ||||||
|         'party.address', 'Address' |  | ||||||
|     ) |  | ||||||
|     order_mobile = fields.Function( |  | ||||||
|         fields.Char('Mobile'), |  | ||||||
|         'on_change_with_order_mobile' |  | ||||||
|     ) |  | ||||||
|     lines = fields.One2Many( |  | ||||||
|         'order.line', 'order', 'Lines' |  | ||||||
|     ) |  | ||||||
|     date = fields.Date("Date", required=True |  | ||||||
|     ) |  | ||||||
|     currency = fields.Many2One( |     currency = fields.Many2One( | ||||||
|         'currency.currency', 'Currency', required=True |         'currency.currency', 'Currency', states={ | ||||||
|     ) |             'readonly': True, | ||||||
|  |             'required': True | ||||||
|  |         }) | ||||||
|  |     number = fields.Char( | ||||||
|  |         "Number", readonly=True) | ||||||
|  |     party = fields.Many2One( | ||||||
|  |         'party.party', "Party", required=True, states=_states) | ||||||
|  |     order_address = fields.Many2One( | ||||||
|  |         'party.address', 'Address', required=True, states=_states) | ||||||
|  |     pickup_location = fields.Selection([ | ||||||
|  |         ("on_site", "On Site"), | ||||||
|  |         ("at_home", "At Home")], 'Pickup Location') | ||||||
|  |     order_mobile = fields.Char('Mobile') | ||||||
|  |     date = fields.Date("Date", required=True, states=_states) | ||||||
|  |     lines = fields.One2Many( | ||||||
|  |         'order.line', 'order', 'Lines', states=_states) | ||||||
|     total_order = fields.Function( |     total_order = fields.Function( | ||||||
|         Monetary("Total", currency='currency', digits='currency'), |         Monetary("Total", currency='currency', digits='currency'), | ||||||
|         'on_change_with_total_order' |         'on_change_with_total_order') | ||||||
|     ) |  | ||||||
|     number = fields.Char( |  | ||||||
|         "Number", readonly=True |  | ||||||
|     ) |  | ||||||
|     state = fields.Selection([ |     state = fields.Selection([ | ||||||
|         ('draft', 'Draft'), |         ('draft', 'Draft'), | ||||||
|         ('confirmed', 'Confirmed')], "State" |         ('confirmed', 'Confirmed')], "State", readonly=True) | ||||||
|     ) |  | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def __setup__(cls): |     def __setup__(cls): | ||||||
|         super(SaleOrder, cls).__setup__() |         super(SaleOrder, cls).__setup__() | ||||||
|         cls._buttons.update({ |         cls._buttons.update({ | ||||||
|             'confirm': {}, |             'confirm': { | ||||||
|  |                 'readonly': Eval('state').in_(['confirmed']), | ||||||
|  |                 'invisible': Eval('state').in_(['confirmed']) | ||||||
|  |             } | ||||||
|         }) |         }) | ||||||
|         cls._transitions |= set(( |         cls._transitions |= set(( | ||||||
|             ('draft', 'confirmed'), |             ('draft', 'confirmed'), | ||||||
|         )) |         )) | ||||||
|  |  | ||||||
|     @classmethod |  | ||||||
|     @ModelView.button |  | ||||||
|     @Workflow.transition('confirmed') |  | ||||||
|     def confirm(cls, orders): |  | ||||||
|         for order in orders: |  | ||||||
|             if order.number: |  | ||||||
|                 continue |  | ||||||
|             else: |  | ||||||
|                 cls.set_code([order]) |  | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def set_code(cls, orders): |     def set_code(cls, orders): | ||||||
|         for order in orders: |         for order in orders: | ||||||
| @@ -84,27 +75,10 @@ class SaleOrder (Workflow, ModelView, ModelSQL): | |||||||
|             'sequence_type.name', '=', "Order")]) |             'sequence_type.name', '=', "Order")]) | ||||||
|         return order_sequence |         return order_sequence | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def default_state(): |  | ||||||
|         return 'draft' |  | ||||||
|  |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def default_company(): |     def default_company(): | ||||||
|         return Transaction().context.get('company') |         return Transaction().context.get('company') | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def default_date(): |  | ||||||
|         return date.today() |  | ||||||
|  |  | ||||||
|     @fields.depends('lines') |  | ||||||
|     def on_change_with_total_order(self, name=None): |  | ||||||
|         total = Decimal('0.0') |  | ||||||
|         if self.lines: |  | ||||||
|             for line in self.lines: |  | ||||||
|                 if line.total_amount: |  | ||||||
|                     total += Decimal(line.total_amount) |  | ||||||
|         return total |  | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def default_currency(cls, **pattern): |     def default_currency(cls, **pattern): | ||||||
|         pool = Pool() |         pool = Pool() | ||||||
| @@ -115,6 +89,29 @@ class SaleOrder (Workflow, ModelView, ModelSQL): | |||||||
|         if company: |         if company: | ||||||
|             return Company(company).currency.id |             return Company(company).currency.id | ||||||
|  |  | ||||||
|  |     @staticmethod | ||||||
|  |     def default_date(): | ||||||
|  |         return date.today() | ||||||
|  |  | ||||||
|  |     @staticmethod | ||||||
|  |     def default_state(): | ||||||
|  |         return 'draft' | ||||||
|  |  | ||||||
|  |     @fields.depends('party') | ||||||
|  |     def on_change_party(self): | ||||||
|  |         if self.party: | ||||||
|  |             self.order_address =\ | ||||||
|  |                 self.party.addresses[0].id if self.party.addresses else None | ||||||
|  |  | ||||||
|  |     @fields.depends('lines') | ||||||
|  |     def on_change_with_total_order(self, name=None): | ||||||
|  |         total = Decimal('0.0') | ||||||
|  |         if self.lines: | ||||||
|  |             for line in self.lines: | ||||||
|  |                 if line.total_amount: | ||||||
|  |                     total += Decimal(line.total_amount) | ||||||
|  |         return total | ||||||
|  |  | ||||||
|     @fields.depends('party') |     @fields.depends('party') | ||||||
|     def on_change_with_order_mobile(self, name=None): |     def on_change_with_order_mobile(self, name=None): | ||||||
|         if self.party: |         if self.party: | ||||||
| @@ -126,42 +123,54 @@ class SaleOrder (Workflow, ModelView, ModelSQL): | |||||||
|             ]) |             ]) | ||||||
|             if mechanisms: |             if mechanisms: | ||||||
|                 return mechanisms[0].value |                 return mechanisms[0].value | ||||||
|         return None |         return | ||||||
|  |  | ||||||
|  |     @classmethod | ||||||
|  |     @ModelView.button | ||||||
|  |     @Workflow.transition('confirmed') | ||||||
|  |     def confirm(cls, orders): | ||||||
|  |         for order in orders: | ||||||
|  |             if order.number: | ||||||
|  |                 continue | ||||||
|  |             else: | ||||||
|  |                 cls.set_code([order]) | ||||||
|  |  | ||||||
|  |  | ||||||
| class OrderLine(ModelView, ModelSQL): | class OrderLine(ModelView, ModelSQL): | ||||||
|     "Order Line" |     "Order Line" | ||||||
|     __name__ = 'order.line' |     __name__ = 'order.line' | ||||||
|  |  | ||||||
|     company = fields.Many2One( |     _states = { | ||||||
|         'company.company', "Company", required=True |         'readonly': Eval('_parent_order.state').in_(['confirmed']) | ||||||
|     ) |     } | ||||||
|     order = fields.Many2One( |     order = fields.Many2One( | ||||||
|         'sale.order', "Sale" |         'sale.order', "Sale") | ||||||
|     ) |     company = fields.Many2One( | ||||||
|  |         'company.company', "Company", states={ | ||||||
|  |             'readonly': True, | ||||||
|  |             'required': True | ||||||
|  |         }) | ||||||
|     currency = fields.Many2One( |     currency = fields.Many2One( | ||||||
|         'currency.currency', 'Currency', required=True |         'currency.currency', 'Currency', states={ | ||||||
|     ) |             'readonly': True, | ||||||
|  |             'required': True | ||||||
|  |         }) | ||||||
|     product = fields.Many2One( |     product = fields.Many2One( | ||||||
|         'product.product', 'Product', required=True |         'product.product', 'Product', required=True, states=_states) | ||||||
|     ) |  | ||||||
|     unit = fields.Many2One( |     unit = fields.Many2One( | ||||||
|         'product.uom', 'Unit' |         'product.uom', 'Unit', required=True, readonly=True) | ||||||
|     ) |  | ||||||
|     product_uom_category = fields.Function( |     product_uom_category = fields.Function( | ||||||
|         fields.Many2One('product.uom.category', 'Product UOM Category'), |         fields.Many2One('product.uom.category', 'Product UOM Category'), | ||||||
|         'on_change_with_product_uom_category' |         'on_change_with_product_uom_category') | ||||||
|     ) |  | ||||||
|     quantity = fields.Float( |     quantity = fields.Float( | ||||||
|         "Quantity", digits=('unit') |         "Quantity", digits=('unit'), required=True, states=_states) | ||||||
|     ) |  | ||||||
|     unitprice = Monetary( |     unitprice = Monetary( | ||||||
|         "Unit Price", digits=price_digits, currency='currency' |         "Unit Price", | ||||||
|     ) |         digits=price_digits, | ||||||
|  |         currency='currency', required=True, states=_states) | ||||||
|     total_amount = fields.Function( |     total_amount = fields.Function( | ||||||
|         Monetary("Total Amount", currency='currency', digits='currency'), |         Monetary("Total Amount", currency='currency', digits='currency'), | ||||||
|         'on_change_with_total_amount' |         'on_change_with_total_amount') | ||||||
|     ) |  | ||||||
|  |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def default_company(): |     def default_company(): | ||||||
| @@ -177,6 +186,11 @@ class OrderLine(ModelView, ModelSQL): | |||||||
|         if company: |         if company: | ||||||
|             return Company(company).currency.id |             return Company(company).currency.id | ||||||
|  |  | ||||||
|  |     @fields.depends('product') | ||||||
|  |     def on_change_product(self): | ||||||
|  |         if self.product: | ||||||
|  |             self.unit = self.product.default_uom.id | ||||||
|  |  | ||||||
|     @fields.depends('product') |     @fields.depends('product') | ||||||
|     def on_change_with_product_uom_category(self, name=None): |     def on_change_with_product_uom_category(self, name=None): | ||||||
|         if self.product: |         if self.product: | ||||||
|   | |||||||
| @@ -39,12 +39,6 @@ this repository contains the full copyright notices and license terms. --> | |||||||
|       <field name="view" ref="sale_order_view_form"/> |       <field name="view" ref="sale_order_view_form"/> | ||||||
|       <field name="act_window" ref="act_sale_order"/> |       <field name="act_window" ref="act_sale_order"/> | ||||||
|     </record> |     </record> | ||||||
|  |  | ||||||
|     <record model="ir.model.button" id="confirm_order_draft"> |  | ||||||
| 	    <field name="name">draft</field> |  | ||||||
| 	    <field name="string">Draft</field> |  | ||||||
| 	    <field name="model">sale.order</field> |  | ||||||
| 	  </record> |  | ||||||
|     <record model="ir.model.button" id="confirm_order_button"> |     <record model="ir.model.button" id="confirm_order_button"> | ||||||
| 	    <field name="name">confirm</field> | 	    <field name="name">confirm</field> | ||||||
| 	    <field name="string">Confirm</field> | 	    <field name="string">Confirm</field> | ||||||
| @@ -61,13 +55,22 @@ this repository contains the full copyright notices and license terms. --> | |||||||
|   </record> |   </record> | ||||||
|   <record model="ir.action.act_window.domain" id="act_order_form_domain_confirm"> |   <record model="ir.action.act_window.domain" id="act_order_form_domain_confirm"> | ||||||
|       <field name="name">Confirm</field> |       <field name="name">Confirm</field> | ||||||
|       <field name="sequence" eval="10"/> |       <field name="sequence" eval="20"/> | ||||||
|       <field name="domain" |       <field name="domain" | ||||||
|           eval="[('state', '=', 'confirmed')]" |           eval="[('state', '=', 'confirmed')]" | ||||||
|           pyson="1"/> |           pyson="1"/> | ||||||
|       <field name="count" eval="True"/> |       <field name="count" eval="True"/> | ||||||
|       <field name="act_window" ref="act_sale_order"/> |       <field name="act_window" ref="act_sale_order"/> | ||||||
|   </record> |   </record> | ||||||
|  |   <record model="ir.action.act_window.domain" id="act_order_form_domain_done"> | ||||||
|  |     <field name="name">Done</field> | ||||||
|  |     <field name="sequence" eval="20"/> | ||||||
|  |     <field name="domain" | ||||||
|  |            eval="[('state', '=', 'done')]" | ||||||
|  |            pyson="1"/> | ||||||
|  |     <field name="count" eval="True"/> | ||||||
|  |     <field name="act_window" ref="act_sale_order"/> | ||||||
|  |   </record> | ||||||
|   <menuitem |   <menuitem | ||||||
|       name="Order" |       name="Order" | ||||||
|       action="act_sale_order" |       action="act_sale_order" | ||||||
|   | |||||||
| @@ -2,9 +2,11 @@ | |||||||
| <!-- This file is part of Tryton.  The COPYRIGHT file at the top level of | <!-- This file is part of Tryton.  The COPYRIGHT file at the top level of | ||||||
| this repository contains the full copyright notices and license terms. --> | this repository contains the full copyright notices and license terms. --> | ||||||
| <form> | <form> | ||||||
|     <group col="2" id="line"> |     <group id="line"> | ||||||
|         <label name="product"/> |         <label name="product"/> | ||||||
|         <field name="product"/> |         <field name="product"/> | ||||||
|  |         <label name="unit"/> | ||||||
|  |         <field name="unit"/> | ||||||
|         <label name="quantity"/> |         <label name="quantity"/> | ||||||
|         <field name="quantity"/> |         <field name="quantity"/> | ||||||
|         <label name="unitprice"/> |         <label name="unitprice"/> | ||||||
|   | |||||||
| @@ -1,23 +1,31 @@ | |||||||
| <?xml version="1.0"?> | <?xml version="1.0"?> | ||||||
| <!-- This file is part of Tryton.  The COPYRIGHT file at the top level of | <!-- This file is part of Tryton.  The COPYRIGHT file at the top level of | ||||||
| this repository contains the full copyright notices and license terms. --> | this repository contains the full copyright notices and license terms. --> | ||||||
| <form> | <form col="6"> | ||||||
|   <label name="party"/> |   <label name="party"/> | ||||||
|   <field name="party"/> |   <field name="party"/> | ||||||
|   <label name="number"/> |   <label name="number"/> | ||||||
|   <field name="number"/> |   <field name="number"/> | ||||||
|   <label name="pickup_location"/> |   <newline/> | ||||||
|   <field name="pickup_location"/> |  | ||||||
|   <label name="order_address"/> |   <label name="order_address"/> | ||||||
|   <field name="order_address"/> |   <field name="order_address"/> | ||||||
|   <label name="order_mobile"/> |   <label name="order_mobile"/> | ||||||
|   <field name="order_mobile"/> |   <field name="order_mobile"/> | ||||||
|  |   <newline/> | ||||||
|   <label name="date"/> |   <label name="date"/> | ||||||
|   <field name="date"/> |   <field name="date"/> | ||||||
|  |   <label name="pickup_location"/> | ||||||
|  |   <field name="pickup_location"/> | ||||||
|  |   <notebook colspan="6"> | ||||||
|  |     <page string="Order" id="Orders"> | ||||||
|       <field name="lines" colspan="4" |       <field name="lines" colspan="4" | ||||||
|              view_ids="sale_order.order_line_view_tree,sale_order.order_line_view_form"/> |              view_ids="sale_order.order_line_view_tree,sale_order.order_line_view_form"/> | ||||||
|       <label name="total_order"/> |       <label name="total_order"/> | ||||||
|       <field name="total_order"/> |       <field name="total_order"/> | ||||||
|  |     </page> | ||||||
|  |   </notebook> | ||||||
|  |   <label name="state"/> | ||||||
|  |   <field name="state"/> | ||||||
|   <group col="-1" colspan="3" id="buttons"> |   <group col="-1" colspan="3" id="buttons"> | ||||||
|     <button name="confirm" string="Confirm" icon="tryton-forward"/> |     <button name="confirm" string="Confirm" icon="tryton-forward"/> | ||||||
|   </group> |   </group> | ||||||
|   | |||||||
| @@ -2,11 +2,11 @@ | |||||||
| <!-- This file is part of Tryton.  The COPYRIGHT file at the top level of | <!-- This file is part of Tryton.  The COPYRIGHT file at the top level of | ||||||
| this repository contains the full copyright notices and license terms. --> | this repository contains the full copyright notices and license terms. --> | ||||||
| <tree> | <tree> | ||||||
|     <field name="party"/> |  | ||||||
|     <field name="number"/> |     <field name="number"/> | ||||||
|     <field name="pickup_location"/> |     <field name="party"/> | ||||||
|     <field name="order_address"/> |     <field name="order_address"/> | ||||||
|     <field name="date"/> |     <field name="date"/> | ||||||
|  |     <field name="pickup_location"/> | ||||||
|     <field name="total_order"/> |     <field name="total_order"/> | ||||||
|     <field name="state"/> |     <field name="state"/> | ||||||
| </tree> | </tree> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user