From 4374cda18f274e2d351941818c0fe69c979c9817 Mon Sep 17 00:00:00 2001 From: Fatemi Lokhandwala Date: Wed, 24 Jan 2018 11:42:32 +0530 Subject: [PATCH] [ADD]:Purchase Indent --- addons/purchase_indent/__init__.py | 4 + addons/purchase_indent/__manifest__.py | 31 + .../demo/puchase_indent_demo.xml | 58 ++ .../purchase_indent/i18n/purchase_indent.pot | 673 ++++++++++++++++++ addons/purchase_indent/models/__init__.py | 3 + .../purchase_indent/models/purchase_indent.py | 637 +++++++++++++++++ .../report/purchase_indent_reports.xml | 17 + .../report/purchase_indent_template.xml | 130 ++++ .../security/ir.model.access.csv | 9 + .../security/purchase_indent_security.xml | 23 + .../static/description/purchase-indent.png | Bin 0 -> 6182 bytes addons/purchase_indent/tests/__init__.py | 3 + .../tests/test_purchase_indent.py | 123 ++++ .../views/purchase_indent_view.xml | 171 +++++ addons/purchase_indent/wizard/__init__.py | 3 + .../wizard/wiz_requisition_request.py | 416 +++++++++++ .../wizard/wiz_requisition_request_view.xml | 101 +++ 17 files changed, 2402 insertions(+) create mode 100644 addons/purchase_indent/__init__.py create mode 100644 addons/purchase_indent/__manifest__.py create mode 100644 addons/purchase_indent/demo/puchase_indent_demo.xml create mode 100644 addons/purchase_indent/i18n/purchase_indent.pot create mode 100644 addons/purchase_indent/models/__init__.py create mode 100644 addons/purchase_indent/models/purchase_indent.py create mode 100644 addons/purchase_indent/report/purchase_indent_reports.xml create mode 100644 addons/purchase_indent/report/purchase_indent_template.xml create mode 100644 addons/purchase_indent/security/ir.model.access.csv create mode 100644 addons/purchase_indent/security/purchase_indent_security.xml create mode 100644 addons/purchase_indent/static/description/purchase-indent.png create mode 100644 addons/purchase_indent/tests/__init__.py create mode 100644 addons/purchase_indent/tests/test_purchase_indent.py create mode 100644 addons/purchase_indent/views/purchase_indent_view.xml create mode 100644 addons/purchase_indent/wizard/__init__.py create mode 100644 addons/purchase_indent/wizard/wiz_requisition_request.py create mode 100644 addons/purchase_indent/wizard/wiz_requisition_request_view.xml diff --git a/addons/purchase_indent/__init__.py b/addons/purchase_indent/__init__.py new file mode 100644 index 00000000..a31f3c40 --- /dev/null +++ b/addons/purchase_indent/__init__.py @@ -0,0 +1,4 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import models +from . import wizard diff --git a/addons/purchase_indent/__manifest__.py b/addons/purchase_indent/__manifest__.py new file mode 100644 index 00000000..f4733b40 --- /dev/null +++ b/addons/purchase_indent/__manifest__.py @@ -0,0 +1,31 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Purchase Indent Flectra', + 'version': '1.0', + 'category': 'Purchase', + 'sequence': 10, + 'summary': 'Purchase Indent', + 'description': """ + Purchase Indent and Agreements""", + 'author': 'Flectrahq', + 'website': 'https://www.flectrahq.com/', + 'depends': [ + 'purchase', + 'purchase_requisition', + ], + 'data': [ + 'security/ir.model.access.csv', + 'security/purchase_indent_security.xml', + 'wizard/wiz_requisition_request_view.xml', + 'views/purchase_indent_view.xml', + 'report/purchase_indent_reports.xml', + 'report/purchase_indent_template.xml', + ], + 'demo': [ + 'demo/puchase_indent_demo.xml', + ], + 'installable': True, + 'application': True, + 'auto_install': False, +} diff --git a/addons/purchase_indent/demo/puchase_indent_demo.xml b/addons/purchase_indent/demo/puchase_indent_demo.xml new file mode 100644 index 00000000..f96358d4 --- /dev/null +++ b/addons/purchase_indent/demo/puchase_indent_demo.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + Whiteboard + + + 2 + 2.0 + + + + + + + + po + + + + + + + Whiteboard + + + + 2 + 2.0 + 2.0 + + + + + + Whiteboard + + + + + + 2 + 100 + + + + + diff --git a/addons/purchase_indent/i18n/purchase_indent.pot b/addons/purchase_indent/i18n/purchase_indent.pot new file mode 100644 index 00000000..8a139cb0 --- /dev/null +++ b/addons/purchase_indent/i18n/purchase_indent.pot @@ -0,0 +1,673 @@ +# Translation of Flectra Server. +# This file contains the translation of the following modules: +# * purchase_indent +# +msgid "" +msgstr "" +"Project-Id-Version: Flectra Server 1.0alpha\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-24 05:17+0000\n" +"PO-Revision-Date: 2018-01-24 05:17+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_agreement_count +msgid "# of Purchase Agreement" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_purchase_order_count +msgid "# of Purchase Order" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:194 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Purchase Indent" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Category:" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Indent Date:" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Shipping address:" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "Agreement" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_requisition_type_id +msgid "Agreement Type" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:424 +#, python-format +msgid "Can't cancel purchase indent which is requested by %s!" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +#: model:ir.ui.view,arch_db:purchase_indent.view_requisition_request_wizard +#: selection:purchase.indent,state:0 +msgid "Cancel" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_category_id +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_category_id +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +msgid "Category" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_company_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_company_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_company_id +msgid "Company" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +#: selection:purchase.indent,state:0 +#: selection:wiz.requisition.request,state:0 +msgid "Confirm" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_requisition_request_wizard +msgid "Create Purchase Agreement" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_requisition_request_wizard +msgid "Create RFQ" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "Create Requisition" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_create_uid +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_create_uid +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_create_uid +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_create_uid +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_create_uid +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_create_uid +msgid "Created by" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_create_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_create_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_create_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_create_date +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_create_date +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_create_date +msgid "Created on" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_date +msgid "Date" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_picking_type_id +msgid "Deliver To" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_name +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_name +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_name +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Description" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_default_location_dest_id_usage +msgid "Destination Location Type" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_display_name +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_display_name +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_display_name +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_display_name +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_display_name +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_display_name +msgid "Display Name" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +#: selection:purchase.indent,state:0 +msgid "Done" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +#: selection:purchase.indent,state:0 +#: selection:wiz.requisition.request,state:0 +msgid "Draft" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_dest_address_id +msgid "Drop Ship Address" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_dummy_wiz_indent_line +msgid "Dummy Wizard Indent Line" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:390 +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_expected_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_expected_date +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_expected_date +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +#, python-format +msgid "Expected Date" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +msgid "Group By" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_intend_history_ids +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "History" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_id +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_id +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_id +msgid "ID" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_purchase_indent_line_id +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_purchase_indent_line_id +msgid "Indent Line Ref" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_indent_line +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_dummy_wiz_indent_line +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_wiz_indent_line +msgid "Indent Lines" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:469 +#, python-format +msgid "Invalid Action!\n" +" You cannot delete a Purchase Indent which is not in 'Draft' or 'Cancel' State!" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line___last_update +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent___last_update +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history___last_update +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line___last_update +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line___last_update +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request___last_update +msgid "Last Modified on" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_write_uid +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_write_uid +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_write_uid +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_write_uid +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_write_uid +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_write_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_write_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_write_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_write_date +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_write_date +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_write_date +msgid "Last Updated on" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +msgid "Name" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_requisition_request_wizard +msgid "Next" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:369 +#, python-format +msgid "No Quantity were found for any line!" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/wizard/wiz_requisition_request.py:97 +#, python-format +msgid "No Requisition Quantity were found for any line!" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "Open Record" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_order_type +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_order_type +msgid "Order Type" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_partner_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_partner_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_partner_id +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_partner_id +msgid "Partner" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,help:purchase_indent.field_dummy_wiz_indent_line_partner_id +#: model:ir.model.fields,help:purchase_indent.field_purchase_indent_line_partner_id +#: model:ir.model.fields,help:purchase_indent.field_purchase_indent_partner_id +msgid "Partner-related data of the user" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:379 +#, python-format +msgid "Please configure outgoing mail server" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:416 +#, python-format +msgid "Please configure your email" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:374 +#, python-format +msgid "Please contact your Administrator \n" +" No user found under 'Purchase Manager'" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_product_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_product_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_product_id +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_product_id +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "Product" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:388 +#, python-format +msgid "Product Name" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_product_uom +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_product_uom +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_product_uom +msgid "Product Unit of Measure" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_purchase_requisition_id +#: selection:wiz.requisition.request,order_type:0 +msgid "Purchase Agreement" +msgstr "" + +#. module: purchase_indent +#: model:ir.actions.act_window,name:purchase_indent.action_flectra_purchase_indent +#: model:ir.model,name:purchase_indent.model_purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_purchase_indent_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_purchase_indent_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_purchase_indent_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_order_line_purchase_indent_ids +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_order_purchase_indent_ids +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_requisition_line_purchase_indent_ids +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_requisition_purchase_indent_ids +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_purchase_indent_ids +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_purchase_indent_id +#: model:ir.ui.menu,name:purchase_indent.menu_flectra_purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "Purchase Indent" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_purchase_indent_history +msgid "Purchase Indent History" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_purchase_indent_line +msgid "Purchase Indent Line" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_order_line_purchase_indent_line_id +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_requisition_line_purchase_indent_line_id +msgid "Purchase Indent Line Ref" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_purchase_order +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_order_id +#: selection:wiz.requisition.request,order_type:0 +msgid "Purchase Order" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_purchase_requisition +msgid "Purchase Requisition" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_purchase_requisition_line +msgid "Purchase Requisition Line" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "Purchases" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,help:purchase_indent.field_purchase_indent_dest_address_id +msgid "Put an address if you want to deliver directly from the vendor to the customer.Otherwise, keep empty to deliver to your own company." +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:389 +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_dummy_product_qty +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_product_qty +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_product_qty +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_product_qty +#, python-format +msgid "Quantity" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:561 +#: code:addons/purchase_indent/tests/test_purchase_indent.py:85 +#: code:addons/purchase_indent/tests/test_purchase_indent.py:90 +#, python-format +msgid "Quantity (%s) can not be Negative!" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_name +msgid "Reference" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Remaining\n" +" Quantity" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_remaining_qty +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_remaining_qty +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_remaining_qty +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_remaining_qty +msgid "Remaining Quantity" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Request\n" +" Quantity" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_indent_requ_date +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_request_date +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +msgid "Request Date" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_product_qty +msgid "Request Quantity" +msgstr "" + +#. module: purchase_indent +#: model:ir.actions.report,name:purchase_indent.report_purchase_indent +msgid "Request for Indent" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +msgid "Requestd By" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_user_id +msgid "Requested By" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Requested By:" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +#: selection:purchase.indent,state:0 +msgid "Requisition" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Requisition\n" +" Quantity" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_requisition_qty +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_requisition_qty +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_requisition_qty +msgid "Requisition Quantity" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/wizard/wiz_requisition_request.py:395 +#, python-format +msgid "Requisition Quantity (%s) can not be Negative!" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:324 +#, python-format +msgid "Requisition Quantity of ' %s ' is more than Remaining Quantity (%s)!" +msgstr "" + +#. module: purchase_indent +#: model:ir.actions.act_window,name:purchase_indent.action_wiz_requisition_request +#: model:ir.ui.view,arch_db:purchase_indent.view_requisition_request_wizard +msgid "Requisition Request" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +msgid "Search Purchase Indent" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_sequence +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_line_sequence +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_sequence +msgid "Sequence" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_form +msgid "Set to Draft" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Sr" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_state +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_state +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_state +#: model:ir.ui.view,arch_db:purchase_indent.view_purchase_indent_search +msgid "State" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_taxes_id +msgid "Taxes" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,help:purchase_indent.field_purchase_indent_default_location_dest_id_usage +msgid "Technical field used to display the Drop Ship Address" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,help:purchase_indent.field_purchase_indent_picking_type_id +msgid "This will determine operation type of incoming shipment" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_purchase_indent_history_requisition_qty +msgid "Transfer Quantity" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "Unit" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_price_unit +msgid "Unit Price" +msgstr "" + +#. module: purchase_indent +#: model:ir.ui.view,arch_db:purchase_indent.report_purchaseindent_document +msgid "VAT:" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_requisition_request_partner_id +msgid "Vendor" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:560 +#: code:addons/purchase_indent/wizard/wiz_requisition_request.py:394 +#, python-format +msgid "Warning" +msgstr "" + +#. module: purchase_indent +#: model:ir.model.fields,field_description:purchase_indent.field_dummy_wiz_indent_line_wizard_indent_id +#: model:ir.model.fields,field_description:purchase_indent.field_wiz_indent_line_wizard_indent_id +msgid "Wiz Requisition Request" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_wiz_indent_line +msgid "Wizard Indent Line" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:191 +#, python-format +msgid "You can not copy Purchase Agreement which have reference of Purchase Indent!" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:142 +#, python-format +msgid "You can not copy Purchase order which have reference of Purchase Indent!" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:135 +#, python-format +msgid "You can not delete Purchase order which have reference of Purchase Indent!" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:184 +#, python-format +msgid "You can not delete agreement which have reference of Purchase Indent!" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:158 +#, python-format +msgid "You can not delete line which have reference of Purchase Indent" +msgstr "" + +#. module: purchase_indent +#: code:addons/purchase_indent/models/purchase_indent.py:362 +#, python-format +msgid "You can't confirm purchase indent which is requested by %s!" +msgstr "" + +#. module: purchase_indent +#: model:ir.model,name:purchase_indent.model_wiz_requisition_request +msgid "wiz.requisition.request" +msgstr "" + diff --git a/addons/purchase_indent/models/__init__.py b/addons/purchase_indent/models/__init__.py new file mode 100644 index 00000000..4fadd208 --- /dev/null +++ b/addons/purchase_indent/models/__init__.py @@ -0,0 +1,3 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import purchase_indent diff --git a/addons/purchase_indent/models/purchase_indent.py b/addons/purchase_indent/models/purchase_indent.py new file mode 100644 index 00000000..36220bd1 --- /dev/null +++ b/addons/purchase_indent/models/purchase_indent.py @@ -0,0 +1,637 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from datetime import datetime + +from flectra.exceptions import Warning, AccessError +from flectra.tools.misc import formatLang + +import flectra.addons.decimal_precision as dp +from flectra import api, fields, models, _ + + +class PurchaseOrder(models.Model): + _inherit = 'purchase.order' + + purchase_indent_ids = fields.Many2many( + 'purchase.indent', string='Purchase Indent') + + @api.onchange('requisition_id') + def _onchange_requisition_id(self): + if not self.requisition_id: + return + + requisition = self.requisition_id + if self.partner_id: + partner = self.partner_id + else: + partner = requisition.vendor_id + payment_term = partner.property_supplier_payment_term_id + company = requisition.company_id + currency = \ + partner.property_purchase_currency_id or \ + company.currency_id + FiscalPosition = self.env['account.fiscal.position'] + fpos = FiscalPosition.get_fiscal_position(partner.id) + fpos = FiscalPosition.browse(fpos) + + self.partner_id = partner.id + self.fiscal_position_id = fpos.id + self.payment_term_id = payment_term.id, + self.company_id = company.id + self.currency_id = currency.id + self.origin = requisition.name + self.partner_ref = requisition.name + self.notes = requisition.description + self.date_order = requisition.date_end or fields.Datetime.now() + self.picking_type_id = requisition.picking_type_id.id + if requisition.type_id.line_copy != 'copy': + return + + order_lines = [] + for line in requisition.line_ids: + product_lang = line.product_id.with_context({ + 'lang': partner.lang, + 'partner_id': partner.id, + }) + name = product_lang.display_name + if product_lang.description_purchase: + name += '\n' + product_lang.description_purchase + + if fpos: + taxes_ids = fpos.map_tax( + line.product_id.supplier_taxes_id.filtered( + lambda tax: tax.company_id == company)) + else: + taxes_ids = line.product_id.supplier_taxes_id.filtered( + lambda tax: tax.company_id == company).ids + + if line.product_uom_id != line.product_id.uom_po_id: + product_qty = line.product_uom_id._compute_quantity( + line.product_qty, line.product_id.uom_po_id) + price_unit = line.product_uom_id._compute_price( + line.price_unit, line.product_id.uom_po_id) + else: + product_qty = line.product_qty + price_unit = line.price_unit + + if requisition.type_id.quantity_copy != 'copy': + product_qty = 0 + + if company.currency_id != currency: + price_unit = requisition.company_id.currency_id.compute( + price_unit, currency) + + order_lines.append((0, 0, { + 'name': name, + 'product_id': line.product_id.id, + 'product_uom': line.product_id.uom_po_id.id, + 'product_qty': product_qty, + 'price_unit': price_unit, + 'taxes_id': [(6, 0, taxes_ids)], + 'date_planned': + requisition.schedule_date or fields.Date.today(), + 'account_analytic_id': line.account_analytic_id.id, + 'purchase_indent_ids': [(6, 0, line.purchase_indent_ids.ids)], + 'purchase_indent_line_id': line.purchase_indent_line_id.id, + })) + self.order_line = order_lines + + @api.multi + def button_draft(self): + self.env['purchase.indent'].set_qty_state_confirm(self, False) + return super(PurchaseOrder, self).button_draft() + + @api.multi + def button_cancel(self): + res = super(PurchaseOrder, self).button_cancel() + for purchase_order_id in self: + self.env['purchase.indent'].set_qty_state_cancel( + purchase_order_id, False) + return res + + @api.model + def create(self, vals): + if vals.get('requisition_id', False): + requisition_id = self.requisition_id.browse( + vals.get('requisition_id', False)) + if requisition_id.purchase_indent_ids: + vals['purchase_indent_ids'] = \ + [(6, 0, requisition_id.purchase_indent_ids.ids)] + return super(PurchaseOrder, self).create(vals) + + @api.multi + def write(self, vals): + res = super(PurchaseOrder, self).write(vals) + if vals.get('requisition_id', False): + self.write({ + 'purchase_indent_ids': + [(6, 0, self.requisition_id.purchase_indent_ids.ids)]}) + return res + + @api.multi + def unlink(self): + for record in self: + if record.purchase_indent_ids: + raise Warning(_("You can not delete Purchase order which \ + have reference of Purchase Indent!")) + return super(PurchaseOrder, self).unlink() + + @api.multi + def copy(self): + self.ensure_one() + if self.purchase_indent_ids: + raise Warning(_("You can not copy Purchase order which have \ + reference of Purchase Indent!")) + return super(PurchaseOrder, self).copy() + + +class PurchaseOrderLine(models.Model): + _inherit = 'purchase.order.line' + + purchase_indent_line_id = fields.Many2one( + 'purchase.indent.line', 'Purchase Indent Line Ref') + purchase_indent_ids = fields.Many2many( + 'purchase.indent', string='Purchase Indent') + + @api.multi + def unlink(self): + if self.purchase_indent_line_id: + raise Warning(_("You can not delete line which have \ + reference of Purchase Indent")) + return super(PurchaseOrderLine, self).unlink() + + +class PurchaseRequisition(models.Model): + _name = 'purchase.requisition' + _inherit = ['purchase.requisition'] + + purchase_indent_ids = fields.Many2many( + 'purchase.indent', string='Purchase Indent') + + @api.multi + def action_draft(self): + self.env['purchase.indent'].set_qty_state_confirm(False, self) + return super(PurchaseRequisition, self).action_draft() + + @api.multi + def action_cancel(self): + self.env['purchase.indent'].set_qty_state_cancel(False, self) + return super(PurchaseRequisition, self).action_cancel() + + @api.multi + def unlink(self): + for record in self: + if record.purchase_indent_ids: + raise Warning(_("You can not delete agreement which have \ + reference of Purchase Indent!")) + return super(PurchaseRequisition, self).unlink() + + @api.multi + def copy(self, default=None): + self.ensure_one() + default = dict(default or {}) + if self.purchase_indent_ids: + raise Warning(_("You can not copy Purchase Agreement which \ + have reference of Purchase Indent!")) + default.update( + name=_("%s (copy)") % (self.name or '')) + return super(PurchaseRequisition, self).copy(default) + + +class PurchaseRequisitionLine(models.Model): + _inherit = 'purchase.requisition.line' + + purchase_indent_line_id = fields.Many2one( + 'purchase.indent.line', 'Purchase Indent Line Ref') + purchase_indent_ids = fields.Many2many( + 'purchase.indent', string='Purchase Indent') + + +class PurchaseIndent(models.Model): + _name = 'purchase.indent' + _inherit = ['mail.thread', 'mail.activity.mixin'] + _description = "Purchase Indent" + + @api.multi + def _compute_order_count(self): + po_list = [] + pa_list = [] + for history_id in self.intend_history_ids: + if history_id.order_id: + po_list.append(history_id.order_id.id) + elif history_id.purchase_requisition_id: + pa_list.append(history_id.purchase_requisition_id.id) + self.purchase_order_count = len(list(set(po_list))) + self.agreement_count = len(list(set(pa_list))) + + @api.model + def _default_picking_type(self): + type_obj = self.env['stock.picking.type'] + company_id = \ + self.env.context.get('company_id') or self.env.user.company_id.id + types = type_obj.search([('code', '=', 'incoming'), + ('warehouse_id.company_id', '=', company_id)]) + if not types: + types = type_obj.search([('code', '=', 'incoming'), + ('warehouse_id', '=', False)]) + return types[:1] + + name = fields.Char( + 'Reference', index=True, copy=False, + readonly=True, track_visibility='onchange') + request_date = fields.Date( + 'Request Date', default=fields.Date.today(), + track_visibility='onchange') + category_id = fields.Many2one( + 'product.category', 'Category', track_visibility='onchange') + state = fields.Selection([ + ('draft', 'Draft'), ('confirm', 'Confirm'), + ('requisition', 'Requisition'), ('done', 'Done'), + ('cancel', 'Cancel')], 'State', + default='draft', track_visibility='onchange') + indent_line = fields.One2many( + 'purchase.indent.line', 'purchase_indent_id', 'Indent Lines') + company_id = fields.Many2one( + 'res.company', string='Company', track_visibility='onchange') + user_id = fields.Many2one( + 'res.users', string='Requested By', + default=lambda self: self.env.uid, + readonly=True, track_visibility='onchange') + partner_id = fields.Many2one( + 'res.partner', related='user_id.partner_id', + string="Partner", track_visibility='onchange') + intend_history_ids = fields.One2many( + 'purchase.indent.history', 'purchase_indent_id', 'History') + purchase_order_count = fields.Integer( + compute='_compute_order_count', string='# of Purchase Order') + agreement_count = fields.Integer( + compute='_compute_order_count', string='# of Purchase Agreement') + dest_address_id = fields.Many2one( + 'res.partner', string='Drop Ship Address', + help="Put an address if you want to deliver directly from the vendor \ + to the customer.Otherwise, keep empty to deliver to your own company.") + picking_type_id = fields.Many2one( + 'stock.picking.type', 'Deliver To', required=True, + default=_default_picking_type, + help="This will determine operation type of incoming shipment") + default_location_dest_id_usage = fields.Selection( + related='picking_type_id.default_location_dest_id.usage', + string='Destination Location Type', + help="Technical field used to display the Drop Ship Address", + readonly=True) + + @api.multi + def set_qty_state_cancel(self, purchase_order_id=False, + purchase_agreement_id=False): + intend_history_ids = [] + indent_line_obj = self.env['purchase.indent.line'] + if purchase_order_id: + intend_history_ids = self.env['purchase.indent.history'].search([ + ('order_id', '=', purchase_order_id.id), + ('purchase_requisition_id', '=', False)]) + elif purchase_agreement_id: + intend_history_ids = self.env['purchase.indent.history'].search([ + ('order_id', '=', False), + ('purchase_requisition_id', '=', purchase_agreement_id.id)]) + for history_id in intend_history_ids: + indent_line_id = indent_line_obj.sudo().search([ + ('product_id', '=', history_id.product_id.id), + ('purchase_indent_id', '=', history_id.purchase_indent_id.id)]) + requisition_qty = \ + indent_line_id.requisition_qty - history_id.requisition_qty + indent_line_id.write({'requisition_qty': requisition_qty}) + history_id.purchase_indent_id.check_state() + history_id.date = datetime.now() + + @api.multi + def set_qty_state_confirm(self, purchase_order_id=False, + purchase_agreement_id=False): + indent_line_obj = self.env['purchase.indent.line'] + intend_history_ids = [] + if purchase_order_id: + intend_history_ids = self.env['purchase.indent.history'].search([ + ('order_id', '=', purchase_order_id.id), + ('state', '=', 'Cancelled')]) + elif purchase_agreement_id: + intend_history_ids = self.env['purchase.indent.history'].search([ + ('purchase_requisition_id', '=', purchase_agreement_id.id), + ('state', '=', 'Cancelled')]) + for history_id in intend_history_ids: + indent_line_id = indent_line_obj.sudo().search([ + ('product_id', '=', history_id.product_id.id), + ('purchase_indent_id', '=', history_id.purchase_indent_id.id)]) + if indent_line_id.requisition_qty + history_id.requisition_qty > \ + indent_line_id.product_qty: + remaining_qty = \ + indent_line_id.product_qty - indent_line_id.requisition_qty + raise Warning(_("Requisition Quantity of ' %s ' is more than \ + Remaining Quantity (%s)!") % ( + history_id.product_id.name, formatLang( + self.env, remaining_qty, digits=2))) + requisition_qty = \ + indent_line_id.requisition_qty + history_id.requisition_qty + indent_line_id.write({'requisition_qty': requisition_qty}) + history_id.purchase_indent_id.check_state() + history_id.date = datetime.now() + + @api.onchange('company_id') + def onchange_company_id(self): + res = {} + user_company_id = self.user_id.company_ids + res['domain'] = {'company_id': [ + ('id', 'in', user_company_id.ids)]} + if len(user_company_id) == 1: + res['domain'] = { + 'company_id': [('id', '=', user_company_id.id)]} + self.company_id = user_company_id.id + return res + + @api.multi + def check_duplicate_product(self): + product_dup_list = [] + for line in self.indent_line: + if line.product_id.id not in product_dup_list: + product_dup_list.append(line.product_id.id) + else: + dup_line_id = self.env['purchase.indent.line'].search([ + ('purchase_indent_id', '=', line.purchase_indent_id.id), + ('product_id', '=', line.product_id.id)], limit=1) + dup_line_id.product_qty += line.product_qty + line.unlink() + + @api.multi + def action_confirm(self): + if self._uid != self.create_uid.id: + raise Warning(_("You can't confirm purchase indent which is \ + requested by %s!") % (self.create_uid.name)) + if not self.indent_line: + raise Warning(_('No Product Line(s) were found!')) + check_pro_qty = [ + line.id for line in self.indent_line if line.product_qty] + if not check_pro_qty: + raise Warning(_("No Quantity were found for any line!")) + self.check_duplicate_product() + group_id = self.sudo().env.ref('purchase.group_purchase_manager') + if not group_id.users: + raise AccessError( + _("Please contact your Administrator \n \ + No user found under 'Purchase Manager'")) + server_id = self.env['ir.mail_server'].search([]) + if not server_id: + raise AccessError( + _("Please configure outgoing mail server")) + email_to = ",".join([user.email + for user in group_id.users if user.email]) + recipient_ids = [user.partner_id.id for user in group_id.users] + if self.env.user.email: + product_qty = ''' + + + + + + ''' + for line in self.indent_line: + qty = (str(formatLang(self.env, line.product_qty, digits=2))) + product_qty += '\ + \ + \ + \ + ' + msg1 = '

Purchase Indent "%s" Confirmed by "%s" for following \ + Products Details.

' % (self.name, self.env.user.name) + msg1 += '

%s

' % (product_qty) + create_values = { + 'body_html': msg1, + 'subject': 'Purchase Indent Confirmed by %s' % ( + self.env.user.name), + 'email_from': self.env.user.email, + 'email_to': email_to, + 'model': 'purchase.indent', + 'res_id': self.id, + 'reply_to': '', + 'recipient_ids': [(6, 0, recipient_ids)], + } + email_id = self.env['mail.mail'].create(create_values) + email_id.send() + else: + raise AccessError(_("Please configure your email")) + self.state = 'confirm' + + @api.multi + def action_cancel(self): + group_id = self.sudo().env.ref('purchase.group_purchase_manager') + if self._uid != self.create_uid.id \ + and self._uid not in group_id.users.ids: + raise Warning(_("Can't cancel purchase indent which is \ + requested by %s!") % (self.create_uid.name)) + self.state = 'cancel' + + @api.multi + def button_draft(self): + self.state = 'draft' + + @api.model + def create(self, vals): + if vals.get('name', 'New') == 'New': + vals['name'] = \ + self.env['ir.sequence'].next_by_code('purchase.indent') or '/' + return super(PurchaseIndent, self).create(vals) + + @api.multi + def get_purchase_order_list(self): + order_list = [ + history_id.order_id.id for history_id in self.intend_history_ids] + return { + 'name': 'Purchase Orders', + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'tree,form,kanban,pivot,graph', + 'res_model': 'purchase.order', + 'domain': [('id', 'in', list(set(order_list)))], + } + + @api.multi + def get_purchase_agreement_list(self): + pr_list = [history_id.purchase_requisition_id.id + for history_id in self.intend_history_ids] + return { + 'name': 'Purchase Agreements', + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'purchase.requisition', + 'domain': [('id', 'in', list(set(pr_list)))], + } + + @api.multi + def unlink(self): + for indent_id in self: + if indent_id.state not in ['draft', 'cancel']: + raise Warning(_("Invalid Action!\n You cannot delete a \ + Purchase Indent which is not in 'Draft' or 'Cancel' State!")) + indent_id.indent_line.unlink() + return super(PurchaseIndent, self).unlink() + + @api.multi + def check_state(self): + check = False + state = '' + for line in self.indent_line: + if line.requisition_qty \ + and line.product_qty != line.requisition_qty: + state = 'requisition' + check = False + break + elif not line.requisition_qty: + if check: + state = 'requisition' + check = False + break + state = 'confirm' + check = False + else: + if line.product_qty != line.requisition_qty: + check = False + break + else: + check = True + if check: + state = 'done' + self.write({'state': state}) + + +class PurchaseIndentLine(models.Model): + _name = 'purchase.indent.line' + _description = "Purchase Indent Line" + + @api.multi + @api.depends('requisition_qty', 'product_qty') + def _compute_get_rem_qty(self): + for self_id in self: + self_id.remaining_qty = \ + self_id.product_qty - self_id.requisition_qty + + purchase_indent_id = fields.Many2one('purchase.indent', 'Purchase Indent') + name = fields.Text(string='Description', required=True) + sequence = fields.Integer(string='Sequence', default=10) + product_qty = fields.Float( + string='Request Quantity', digits=dp.get_precision('Discount')) + expected_date = fields.Date( + string='Expected Date', index=True, default=fields.Date.today()) + product_uom = fields.Many2one( + 'product.uom', string='Product Unit of Measure') + product_id = fields.Many2one( + 'product.product', string='Product', + change_default=True, required=True) + company_id = fields.Many2one( + 'res.company', related='purchase_indent_id.company_id', + string='Company', store=True, readonly=True) + requisition_qty = fields.Float( + string="Requisition Quantity", + digits=dp.get_precision('Discount')) + partner_id = fields.Many2one( + 'res.partner', related='purchase_indent_id.partner_id', + string='Partner', readonly=True, store=True) + remaining_qty = fields.Float( + compute="_compute_get_rem_qty", string='Remaining Quantity', + digits=dp.get_precision('Discount'), store=True) + + @api.onchange('product_id') + def onchange_product_id(self): + result = {} + if not self.product_id: + return result + self.product_uom = self.product_id.uom_po_id or self.product_id.uom_id + result['domain'] = {'product_uom': [ + ('category_id', '=', self.product_id.uom_id.category_id.id)]} + product_lang = self.product_id.with_context({ + 'lang': self.partner_id.lang, + 'partner_id': self.partner_id.id, + }) + self.name = product_lang.display_name + if product_lang.description_purchase: + self.name += '\n' + product_lang.description_purchase + return result + + @api.onchange('product_qty') + def onchange_product_qty(self): + warning = {} + if self.product_qty < 0: + warning.update({ + 'title': _("Warning"), + 'message': _("Quantity (%s) can not be Negative!") % ( + formatLang(self.env, self.product_qty, digits=2)) + }) + self.product_qty = False + return {'warning': warning} + + +class PurchaseIndentHistory(models.Model): + _name = 'purchase.indent.history' + _description = "Purchase Indent History" + _order = 'id desc' + + @api.multi + @api.depends('order_id.state', 'purchase_requisition_id.state') + def _compute_get_state(self): + for history_id in self: + name = "" + if history_id.order_id: + po_dict = dict(history_id.order_id.fields_get( + allfields=['state'])['state']['selection']) + name = po_dict.get(history_id.order_id.state) + elif history_id.purchase_requisition_id: + pa_dict = dict(history_id.purchase_requisition_id.fields_get( + allfields=['state'])['state']['selection']) + name = pa_dict.get(history_id.purchase_requisition_id.state) + history_id.state = name + + @api.multi + @api.depends('requisition_qty', 'product_qty', 'state') + def _compute_get_rem_qty(self): + for self_id in self: + if self_id.state == 'Cancelled': + self_id.remaining_qty = self_id.product_qty + else: + self_id.remaining_qty = \ + self_id.product_qty - self_id.requisition_qty + + purchase_indent_id = fields.Many2one('purchase.indent', 'Purchase Indent') + product_id = fields.Many2one( + 'product.product', string='Product', + domain=[('purchase_ok', '=', True)], + change_default=True, required=True) + order_id = fields.Many2one('purchase.order', 'Purchase Order') + purchase_requisition_id = fields.Many2one( + 'purchase.requisition', 'Purchase Agreement') + date = fields.Datetime('Date') + product_qty = fields.Float( + 'Quantity', digits=dp.get_precision('Discount')) + requisition_qty = fields.Float( + string="Transfer Quantity", + digits=dp.get_precision('Discount')) + state = fields.Char(compute='_compute_get_state', string='State', + store=True) + remaining_qty = fields.Float( + compute="_compute_get_rem_qty", string='Remaining Quantity', + digits=dp.get_precision('Discount'), store=True) + + @api.multi + def open_form_view(self): + res_id = model = False + if self.order_id: + res_id = self.order_id.id + model = 'purchase.order' + elif self.purchase_requisition_id: + res_id = self.purchase_requisition_id.id + model = 'purchase.requisition' + return { + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': model, + 'res_id': res_id, + 'view_id': False, + 'type': 'ir.actions.act_window', + } diff --git a/addons/purchase_indent/report/purchase_indent_reports.xml b/addons/purchase_indent/report/purchase_indent_reports.xml new file mode 100644 index 00000000..fe1929e0 --- /dev/null +++ b/addons/purchase_indent/report/purchase_indent_reports.xml @@ -0,0 +1,17 @@ + + + + + + + 'Request for Indent'+'-'+(object.name) + + + diff --git a/addons/purchase_indent/report/purchase_indent_template.xml b/addons/purchase_indent/report/purchase_indent_template.xml new file mode 100644 index 00000000..ae3b473d --- /dev/null +++ b/addons/purchase_indent/report/purchase_indent_template.xml @@ -0,0 +1,130 @@ + + + + + + + + + diff --git a/addons/purchase_indent/security/ir.model.access.csv b/addons/purchase_indent/security/ir.model.access.csv new file mode 100644 index 00000000..e21e9376 --- /dev/null +++ b/addons/purchase_indent/security/ir.model.access.csv @@ -0,0 +1,9 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_purchase_indent_line,access_purchase_indent_line,model_purchase_indent_line,purchase.group_purchase_manager,1,1,1,1 +access_purchase_indent,access_purchase_indent,model_purchase_indent,purchase.group_purchase_manager,1,1,1,1 +access_purchase_indent_history,access_purchase_indent_history,model_purchase_indent_history,purchase.group_purchase_manager,1,1,1,1 +access_purchase_indent_line_user,access_purchase_indent_line_user,model_purchase_indent_line,purchase.group_purchase_user,1,1,1,1 +access_purchase_indent_user,access_purchase_indent_user,model_purchase_indent,purchase.group_purchase_user,1,1,1,1 +access_purchase_indent_history_user,access_purchase_indent_history_user,model_purchase_indent_history,purchase.group_purchase_user,1,1,0,0 +access_ir_mail_server_user,access_ir_mail_server_user,base.model_ir_mail_server,purchase.group_purchase_user,1,0,0,0 +access_ir_mail_server_manager,access_ir_mail_server_manager,base.model_ir_mail_server,purchase.group_purchase_manager,1,0,0,0 diff --git a/addons/purchase_indent/security/purchase_indent_security.xml b/addons/purchase_indent/security/purchase_indent_security.xml new file mode 100644 index 00000000..8d57f82d --- /dev/null +++ b/addons/purchase_indent/security/purchase_indent_security.xml @@ -0,0 +1,23 @@ + + + + + + Purchase Indent multi-company + + + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + + + + Purchase Indent Line multi-company + + + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + + + diff --git a/addons/purchase_indent/static/description/purchase-indent.png b/addons/purchase_indent/static/description/purchase-indent.png new file mode 100644 index 0000000000000000000000000000000000000000..9f75d7464851c43cdd6392e5ce7853700edf7731 GIT binary patch literal 6182 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 Eg4sLEH2?qr literal 0 HcmV?d00001 diff --git a/addons/purchase_indent/tests/__init__.py b/addons/purchase_indent/tests/__init__.py new file mode 100644 index 00000000..10752aa5 --- /dev/null +++ b/addons/purchase_indent/tests/__init__.py @@ -0,0 +1,3 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +from . import test_purchase_indent diff --git a/addons/purchase_indent/tests/test_purchase_indent.py b/addons/purchase_indent/tests/test_purchase_indent.py new file mode 100644 index 00000000..67329bca --- /dev/null +++ b/addons/purchase_indent/tests/test_purchase_indent.py @@ -0,0 +1,123 @@ +# Part of Flectra See LICENSE file for full copyright and licensing details. + +import logging +from datetime import datetime + +from flectra.exceptions import Warning +from flectra.tests.common import TransactionCase +from flectra.tools.misc import formatLang + +from flectra import _ + + +class TestPurchaseIndent(TransactionCase): + + def setUp(self): + super(TestPurchaseIndent, self).setUp() + self.PurchaseIndent = self.env['purchase.indent'] + self.PurchaseIndentLine = self.env['purchase.indent.line'] + self.Requisition_Req = self.env['wiz.requisition.request'] + + def test_00_purchase_indent_flow(self): + self.partner_id = self.env.ref('base.res_partner_address_12') + self.category_id = self.env.ref('product.product_category_5') + self.product_id_1 = self.env.ref('product.product_product_24') + self.product_id_2 = self.env.ref('product.product_product_16') + self.product_id_3 = self.env.ref('product.consu_delivery_03') + self.company_id = self.env.ref('base.main_company') + self.agreement_type_id = \ + self.env.ref('purchase_requisition.type_multi') + + purchase_indent_vals_1 = { + 'company_id': self.company_id.id, + 'category_id': self.category_id.id, + 'request_date': datetime.today(), + 'user_id': self.env.user.id, + 'indent_line': [ + (0, 0, { + 'name': self.product_id_1.name, + 'product_id': self.product_id_1.id, + 'product_qty': 5.0, + 'product_uom': self.product_id_1.uom_po_id.id, + }), + (0, 0, { + 'name': self.product_id_2.name, + 'product_id': self.product_id_2.id, + 'product_qty': 15.0, + 'product_uom': self.product_id_2.uom_po_id.id, + })], + } + + purchase_indent_vals_2 = { + 'company_id': self.company_id.id, + 'category_id': self.category_id.id, + 'request_date': datetime.today(), + 'user_id': self.env.user.id, + 'indent_line': [ + (0, 0, { + 'name': self.product_id_3.name, + 'product_id': self.product_id_3.id, + 'product_qty': 20.0, + 'product_uom': self.product_id_3.uom_po_id.id, + }), + (0, 0, { + 'name': self.product_id_1.name, + 'product_id': self.product_id_1.id, + 'product_qty': 25.0, + 'product_uom': self.product_id_1.uom_po_id.id, + }), + (0, 0, { + 'name': self.product_id_2.name, + 'product_id': self.product_id_2.id, + 'product_qty': 5.0, + 'product_uom': self.product_id_2.uom_po_id.id, + })], + } + self.pi = self.PurchaseIndent.create(purchase_indent_vals_1) + self.pi_1 = self.PurchaseIndent.create(purchase_indent_vals_2) + self.assertTrue( + self.pi, 'Purchase Indent: no purchase indent created') + self.assertTrue( + self.pi_1, 'Purchase Indent: no purchase indent created') + + for line in self.pi.indent_line: + if line.product_qty < 0: + raise Warning(_("Quantity (%s) can not be Negative!") % ( + formatLang(self.env, line.product_qty, digits=2))) + + for line in self.pi_1.indent_line: + if line.product_qty < 0: + raise Warning(_("Quantity (%s) can not be Negative!") % ( + formatLang(self.env, line.product_qty, digits=2))) + + self.pi.action_confirm() + self.pi_1.action_confirm() + + requisition_id = self.Requisition_Req.create({ + 'category_id': self.category_id.id, + 'order_type': 'po', + 'purchase_indent_id': self.pi.id, + }) + requisition_id.onchange_purchase_indent_id() + requisition_id.dummy_wiz_indent_line[0].write({'requisition_qty': 5}) + requisition_id.dummy_wiz_indent_line[2].write({'requisition_qty': 20}) + requisition_id.act_next() + requisition_id.write({'partner_id': self.partner_id.id}) + for line in requisition_id.wiz_indent_line: + line.write({'price_unit': 100}) + requisition_id.action_create() + requisition_id_1 = self.Requisition_Req.create({ + 'category_id': self.category_id.id, + 'order_type': 'pa', + 'purchase_indent_id': self.pi_1.id, + 'requisition_type_id': self.agreement_type_id.id, + }) + + requisition_id_1.onchange_purchase_indent_id() + requisition_id_1.dummy_wiz_indent_line[1].write({'requisition_qty': 4}) + requisition_id_1.dummy_wiz_indent_line[2].write({'requisition_qty': 5}) + requisition_id_1.act_next() + for line in requisition_id_1.wiz_indent_line: + line.write({'price_unit': 100}) + requisition_id_1.action_create() + logging.info('\n\nSuccessful: Purchase Agreement Created!') diff --git a/addons/purchase_indent/views/purchase_indent_view.xml b/addons/purchase_indent/views/purchase_indent_view.xml new file mode 100644 index 00000000..37fc086b --- /dev/null +++ b/addons/purchase_indent/views/purchase_indent_view.xml @@ -0,0 +1,171 @@ + + + + + Purchase inherited form + purchase.order + + + + + + + + + + + + + + Purchase Requisition Inherited Form + purchase.requisition + + + + + + + + + + + + + + Purchase indent tree + purchase.indent + + + + + + + + + + + + + + purchase.indent.form + purchase.indent + +
+
+
+ +
+ + +
+
+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
''' + _("Product Name") + '''''' + _("Quantity") + '''''' + _("Expected Date") + '''
' + str(line.product_id.name) + '' + qty + '' + str(line.expected_date) + '