mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-13 18:21:22 +00:00
moved directory structure
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
# DocType Mapper, Delivery Note-Installation Note
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:34',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-09-15 15:04:42',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': 'Delivery Note-Installation Note',
|
||||
'parentfield': 'table_mapper_details',
|
||||
'parenttype': 'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'map': 'Yes',
|
||||
'name': '__common__',
|
||||
'parent': 'Delivery Note-Installation Note',
|
||||
'parentfield': 'field_mapper_details',
|
||||
'parenttype': 'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': 'Delivery Note',
|
||||
'module': 'Selling',
|
||||
'name': '__common__',
|
||||
'ref_doc_submitted': 1,
|
||||
'to_doctype': 'Installation Note'
|
||||
},
|
||||
|
||||
# DocType Mapper, Delivery Note-Installation Note
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': 'Delivery Note-Installation Note'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': '=',
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'company',
|
||||
'match_id': 0,
|
||||
'to_field': 'company'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': '=',
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'customer',
|
||||
'match_id': 0,
|
||||
'to_field': 'customer'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'name',
|
||||
'match_id': 0,
|
||||
'to_field': 'delivery_note_no'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'name',
|
||||
'match_id': 1,
|
||||
'to_field': 'prevdoc_detail_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'parent',
|
||||
'match_id': 1,
|
||||
'to_field': 'prevdoc_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'parenttype',
|
||||
'match_id': 1,
|
||||
'to_field': 'prevdoc_doctype'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'eval: flt(obj.qty) - flt(obj.installed_qty)',
|
||||
'match_id': 1,
|
||||
'to_field': 'qty'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'posting_date',
|
||||
'match_id': 2,
|
||||
'to_field': 'prevdoc_date'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'serial_no',
|
||||
'match_id': 1,
|
||||
'to_field': 'serial_no'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_field': 'delivery_note_details',
|
||||
'from_table': 'Delivery Note Item',
|
||||
'match_id': 1,
|
||||
'to_field': 'installed_item_details',
|
||||
'to_table': 'Installation Note Item',
|
||||
'validation_logic': 'qty > ifnull(installed_qty,0) and docstatus = 1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_table': 'Delivery Note',
|
||||
'match_id': 0,
|
||||
'to_table': 'Installation Note',
|
||||
'validation_logic': 'docstatus = 1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_table': 'Delivery Note',
|
||||
'match_id': 2,
|
||||
'reference_doctype_key': 'prevdoc_doctype',
|
||||
'reference_key': 'prevdoc_docname',
|
||||
'to_field': 'installed_item_details',
|
||||
'to_table': 'Installation Note Item',
|
||||
'validation_logic': 'docstatus = 1'
|
||||
}
|
||||
]
|
||||
84
selling/DocType Mapper/Lead-Customer/Lead-Customer.txt
Normal file
84
selling/DocType Mapper/Lead-Customer/Lead-Customer.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
# DocType Mapper, Lead-Customer
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:34',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-09-14 12:36:24',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_table': 'Lead',
|
||||
'match_id': 0,
|
||||
'name': '__common__',
|
||||
'parent': 'Lead-Customer',
|
||||
'parentfield': 'table_mapper_details',
|
||||
'parenttype': 'DocType Mapper',
|
||||
'to_table': 'Customer',
|
||||
'validation_logic': 'name is not null'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'map': 'Yes',
|
||||
'match_id': 0,
|
||||
'name': '__common__',
|
||||
'parent': 'Lead-Customer',
|
||||
'parentfield': 'field_mapper_details',
|
||||
'parenttype': 'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': 'Lead',
|
||||
'module': 'Selling',
|
||||
'name': '__common__',
|
||||
'to_doctype': 'Customer'
|
||||
},
|
||||
|
||||
# DocType Mapper, Lead-Customer
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': 'Lead-Customer'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'name',
|
||||
'to_field': 'lead_name'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'company_name',
|
||||
'to_field': 'customer_name'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'contact_no',
|
||||
'to_field': 'phone_1'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'fax',
|
||||
'to_field': 'fax_1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail'
|
||||
}
|
||||
]
|
||||
87
selling/DocType Mapper/Lead-Opportunity/Lead-Opportunity.txt
Normal file
87
selling/DocType Mapper/Lead-Opportunity/Lead-Opportunity.txt
Normal file
@@ -0,0 +1,87 @@
|
||||
# DocType Mapper, Lead-Opportunity
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:34',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-04-03 12:49:50',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_table': u'Lead',
|
||||
'match_id': 0,
|
||||
'name': '__common__',
|
||||
'parent': u'Lead-Opportunity',
|
||||
'parentfield': u'table_mapper_details',
|
||||
'parenttype': u'DocType Mapper',
|
||||
'to_table': u'Opportunity',
|
||||
'validation_logic': u'name is not null'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'match_id': 0,
|
||||
'name': '__common__',
|
||||
'parent': u'Lead-Opportunity',
|
||||
'parentfield': u'field_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': u'Lead',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'to_doctype': u'Opportunity'
|
||||
},
|
||||
|
||||
# DocType Mapper, Lead-Opportunity
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': u'Lead-Opportunity'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'campaign_name',
|
||||
'map': u'Yes',
|
||||
'to_field': u'campaign'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'doctype',
|
||||
'map': u'Yes',
|
||||
'to_field': u'enquiry_from'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'name',
|
||||
'map': u'Yes',
|
||||
'to_field': u'lead'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'status',
|
||||
'map': u'No',
|
||||
'to_field': u'status'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,146 @@
|
||||
# DocType Mapper, Opportunity-Quotation
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:34',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-04-03 12:49:50',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity-Quotation',
|
||||
'parentfield': u'table_mapper_details',
|
||||
'parenttype': u'DocType Mapper',
|
||||
'validation_logic': u'docstatus=1'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity-Quotation',
|
||||
'parentfield': u'field_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': u'Opportunity',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'ref_doc_submitted': 1,
|
||||
'to_doctype': u'Quotation'
|
||||
},
|
||||
|
||||
# DocType Mapper, Opportunity-Quotation
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': u'Opportunity-Quotation'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'uom',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'stock_uom'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'name',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'enq_no'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'parent',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'prevdoc_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'parenttype',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'prevdoc_doctype'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'enquiry_from',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'quotation_to'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'enquiry_type',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'order_type'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'transaction_date',
|
||||
'map': u'No',
|
||||
'match_id': 0,
|
||||
'to_field': u'transaction_date'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'status',
|
||||
'map': u'No',
|
||||
'match_id': 0,
|
||||
'to_field': u'status'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'naming_series',
|
||||
'map': u'No',
|
||||
'match_id': 0,
|
||||
'to_field': u'naming_series'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_table': u'Opportunity',
|
||||
'match_id': 0,
|
||||
'to_table': u'Quotation'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'enq_details',
|
||||
'from_table': u'Opportunity Item',
|
||||
'match_id': 1,
|
||||
'to_field': u'quotation_details',
|
||||
'to_table': u'Quotation Item'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,64 @@
|
||||
# DocType Mapper, Project-Sales Order
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-09-01 15:47:59',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-09-15 15:04:43',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'ashwini@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_table': 'Project',
|
||||
'match_id': 0,
|
||||
'name': '__common__',
|
||||
'parent': 'Project-Sales Order',
|
||||
'parentfield': 'table_mapper_details',
|
||||
'parenttype': 'DocType Mapper',
|
||||
'to_table': 'Sales Order',
|
||||
'validation_logic': 'name is not null'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'checking_operator': '=',
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'customer',
|
||||
'map': 'Yes',
|
||||
'match_id': 0,
|
||||
'name': '__common__',
|
||||
'parent': 'Project-Sales Order',
|
||||
'parentfield': 'field_mapper_details',
|
||||
'parenttype': 'DocType Mapper',
|
||||
'to_field': 'customer'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': 'DocType Mapper',
|
||||
'from_doctype': 'Project',
|
||||
'module': 'Selling',
|
||||
'name': '__common__',
|
||||
'to_doctype': 'Sales Order'
|
||||
},
|
||||
|
||||
# DocType Mapper, Project-Sales Order
|
||||
{
|
||||
'doctype': 'DocType Mapper',
|
||||
'name': 'Project-Sales Order'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,165 @@
|
||||
# DocType Mapper, Quotation-Sales Order
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:35',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-09-14 12:36:24',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': 'Quotation-Sales Order',
|
||||
'parentfield': 'table_mapper_details',
|
||||
'parenttype': 'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': 'Quotation-Sales Order',
|
||||
'parentfield': 'field_mapper_details',
|
||||
'parenttype': 'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': 'Quotation',
|
||||
'module': 'Selling',
|
||||
'name': '__common__',
|
||||
'ref_doc_submitted': 1,
|
||||
'to_doctype': 'Sales Order'
|
||||
},
|
||||
|
||||
# DocType Mapper, Quotation-Sales Order
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': 'Quotation-Sales Order'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': '>=',
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'transaction_date',
|
||||
'map': 'No',
|
||||
'match_id': 0,
|
||||
'to_field': 'transaction_date'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'transaction_date',
|
||||
'map': 'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': 'quotation_date'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'name',
|
||||
'map': 'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': 'quotation_no'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': '=',
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'company',
|
||||
'map': 'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': 'company'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': '=',
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'fiscal_year',
|
||||
'map': 'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': 'fiscal_year'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'parent',
|
||||
'map': 'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': 'prevdoc_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'naming_series',
|
||||
'map': 'No',
|
||||
'match_id': 0,
|
||||
'to_field': 'naming_series'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail',
|
||||
'from_field': 'status',
|
||||
'map': 'No',
|
||||
'match_id': 0,
|
||||
'to_field': 'status'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_field': 'sales_team',
|
||||
'from_table': 'Sales Team',
|
||||
'match_id': 3,
|
||||
'to_field': 'sales_team',
|
||||
'to_table': 'Sales Team',
|
||||
'validation_logic': 'name is not null'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_field': 'other_charges',
|
||||
'from_table': 'Sales Taxes and Charges',
|
||||
'match_id': 2,
|
||||
'to_field': 'other_charges',
|
||||
'to_table': 'Sales Taxes and Charges',
|
||||
'validation_logic': 'name is not null'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_field': 'quotation_details',
|
||||
'from_table': 'Quotation Item',
|
||||
'match_id': 1,
|
||||
'reference_doctype_key': 'prevdoc_doctype',
|
||||
'to_field': 'sales_order_details',
|
||||
'to_table': 'Sales Order Item',
|
||||
'validation_logic': 'name is not null'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail',
|
||||
'from_table': 'Quotation',
|
||||
'match_id': 0,
|
||||
'reference_key': 'prevdoc_docname',
|
||||
'to_table': 'Sales Order',
|
||||
'validation_logic': 'docstatus = 1'
|
||||
}
|
||||
]
|
||||
28
selling/Print Format/Quotation Classic/Quotation Classic.txt
Normal file
28
selling/Print Format/Quotation Classic/Quotation Classic.txt
Normal file
File diff suppressed because one or more lines are too long
28
selling/Print Format/Quotation Modern/Quotation Modern.txt
Normal file
28
selling/Print Format/Quotation Modern/Quotation Modern.txt
Normal file
File diff suppressed because one or more lines are too long
28
selling/Print Format/Quotation Spartan/Quotation Spartan.txt
Normal file
28
selling/Print Format/Quotation Spartan/Quotation Spartan.txt
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
selling/__init__.py
Normal file
8
selling/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from __future__ import unicode_literals
|
||||
install_docs = [
|
||||
{"doctype":"Role", "role_name":"Customer", "name":"Customer"},
|
||||
{"doctype":"Role", "role_name":"Partner", "name":"Partner"},
|
||||
{"doctype":"Role", "role_name":"Sales Manager", "name":"Sales Manager"},
|
||||
{"doctype":"Role", "role_name":"Sales Master Manager", "name":"Sales Master Manager"},
|
||||
{"doctype":"Role", "role_name":"Sales User", "name":"Sales User"},
|
||||
]
|
||||
1
selling/doctype/__init__.py
Normal file
1
selling/doctype/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
1
selling/doctype/campaign/__init__.py
Normal file
1
selling/doctype/campaign/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
26
selling/doctype/campaign/campaign.js
Normal file
26
selling/doctype/campaign/campaign.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
//--------- ONLOAD -------------
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
162
selling/doctype/campaign/campaign.txt
Normal file
162
selling/doctype/campaign/campaign.txt
Normal file
@@ -0,0 +1,162 @@
|
||||
# DocType, Campaign
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-07-03 13:30:38',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-12 13:21:52',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1326102553',
|
||||
'allow_trash': 1,
|
||||
'autoname': u'field:campaign_name',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'description': u'Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Campaign',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Campaign',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1,
|
||||
'submit': 0
|
||||
},
|
||||
|
||||
# DocType, Campaign
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Campaign'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'oldfieldname': u'trash_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'campaign',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Campaign',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'campaign_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Campaign Name',
|
||||
'oldfieldname': u'campaign_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'width': u'300px'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/customer/__init__.py
Normal file
1
selling/doctype/customer/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
209
selling/doctype/customer/customer.js
Normal file
209
selling/doctype/customer/customer.js
Normal file
@@ -0,0 +1,209 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
wn.require('erpnext/setup/doctype/contact_control/contact_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
/* ********************************* onload ********************************************* */
|
||||
|
||||
cur_frm.cscript.onload = function(doc,dt,dn){
|
||||
// history doctypes and scripts
|
||||
cur_frm.history_dict = {
|
||||
'Quotation' : 'cur_frm.cscript.make_qtn_list(this.body, this.doc)',
|
||||
'Sales Order' : 'cur_frm.cscript.make_so_list(this.body, this.doc)',
|
||||
'Delivery Note' : 'cur_frm.cscript.make_dn_list(this.body, this.doc)',
|
||||
'Sales Invoice' : 'cur_frm.cscript.make_si_list(this.body, this.doc)'
|
||||
}
|
||||
// make address, contact, shipping, history list body
|
||||
cur_frm.cscript.make_hl_body();
|
||||
//cur_frm.cscript.make_sl_body();
|
||||
|
||||
cur_frm.cscript.load_defaults(doc, dt, dn);
|
||||
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.load_defaults = function(doc, dt, dn) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if(!(doc.__islocal && doc.lead_name)) { return; }
|
||||
|
||||
var fields_to_refresh = LocalDB.set_default_values(doc);
|
||||
if(fields_to_refresh) { refresh_many(fields_to_refresh); }
|
||||
}
|
||||
|
||||
cur_frm.add_fetch('lead_name', 'company_name', 'customer_name');
|
||||
cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate');
|
||||
|
||||
/* ********************************* refresh ********************************************* */
|
||||
|
||||
cur_frm.cscript.refresh = function(doc,dt,dn) {
|
||||
if(sys_defaults.cust_master_name == 'Customer Name')
|
||||
hide_field('naming_series');
|
||||
else
|
||||
unhide_field('naming_series');
|
||||
|
||||
if(doc.__islocal){
|
||||
hide_field(['address_html','contact_html']);
|
||||
//cur_frm.cscript.set_hl_msg(doc);
|
||||
//cur_frm.cscript.set_sl_msg(doc);
|
||||
}else{
|
||||
unhide_field(['address_html','contact_html']);
|
||||
// make lists
|
||||
cur_frm.cscript.make_address(doc,dt,dn);
|
||||
cur_frm.cscript.make_contact(doc,dt,dn);
|
||||
cur_frm.cscript.make_history(doc,dt,dn);
|
||||
cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
//cur_frm.cscript.make_shipping_address(doc,dt,dn);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_address = function() {
|
||||
if(!cur_frm.address_list) {
|
||||
cur_frm.address_list = new wn.ui.Listing({
|
||||
parent: cur_frm.fields_dict['address_html'].wrapper,
|
||||
page_length: 2,
|
||||
new_doctype: "Address",
|
||||
get_query: function() {
|
||||
return "select name, address_type, address_line1, address_line2, city, state, country, pincode, fax, email_id, phone, is_primary_address, is_shipping_address from tabAddress where customer='"+cur_frm.docname+"' and docstatus != 2 order by is_primary_address desc"
|
||||
},
|
||||
as_dict: 1,
|
||||
no_results_message: 'No addresses created',
|
||||
render_row: cur_frm.cscript.render_address_row,
|
||||
});
|
||||
// note: render_address_row is defined in contact_control.js
|
||||
}
|
||||
cur_frm.address_list.run();
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_contact = function() {
|
||||
if(!cur_frm.contact_list) {
|
||||
cur_frm.contact_list = new wn.ui.Listing({
|
||||
parent: cur_frm.fields_dict['contact_html'].wrapper,
|
||||
page_length: 2,
|
||||
new_doctype: "Contact",
|
||||
get_query: function() {
|
||||
return "select name, first_name, last_name, email_id, phone, mobile_no, department, designation, is_primary_contact from tabContact where customer='"+cur_frm.docname+"' and docstatus != 2 order by is_primary_contact desc"
|
||||
},
|
||||
as_dict: 1,
|
||||
no_results_message: 'No contacts created',
|
||||
render_row: cur_frm.cscript.render_contact_row,
|
||||
});
|
||||
// note: render_contact_row is defined in contact_control.js
|
||||
}
|
||||
cur_frm.contact_list.run();
|
||||
|
||||
}
|
||||
|
||||
/* ********************************* client triggers ************************************** */
|
||||
|
||||
// ---------------
|
||||
// customer group
|
||||
// ---------------
|
||||
cur_frm.fields_dict['customer_group'].get_query = function(doc,dt,dn) {
|
||||
return 'SELECT `tabCustomer Group`.`name`, `tabCustomer Group`.`parent_customer_group` FROM `tabCustomer Group` WHERE `tabCustomer Group`.`is_group` = "No" AND `tabCustomer Group`.`docstatus`!= 2 AND `tabCustomer Group`.%(key)s LIKE "%s" ORDER BY `tabCustomer Group`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
// -----
|
||||
// lead
|
||||
// -----
|
||||
cur_frm.fields_dict['lead_name'].get_query = function(doc,dt,dn){
|
||||
return 'SELECT `tabLead`.`name` FROM `tabLead` WHERE `tabLead`.`status`!="Converted" AND `tabLead`.%(key)s LIKE "%s" ORDER BY `tabLead`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
// Transaction History
|
||||
// functions called by these functions are defined in communication.js
|
||||
cur_frm.cscript.make_qtn_list = function(parent, doc) {
|
||||
cur_frm.cscript.get_common_list_view(parent, doc, 'Quotation');
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_so_list = function(parent, doc) {
|
||||
cur_frm.cscript.get_common_list_view(parent, doc, 'Sales Order');
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_dn_list = function(parent, doc) {
|
||||
cur_frm.cscript.get_common_list_view(parent, doc, 'Delivery Note');
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_common_list_view = function(parent, doc, doctype) {
|
||||
var ListView = wn.views.ListView.extend({
|
||||
init: function(doclistview) {
|
||||
this._super(doclistview);
|
||||
this.fields = this.fields.concat([
|
||||
"`tab" + doctype + "`.status",
|
||||
"`tab" + doctype + "`.currency",
|
||||
"ifnull(`tab" + doctype + "`.grand_total_export, 0) as grand_total_export",
|
||||
|
||||
]);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
data.grand_total_export = data.currency + " " + fmt_money(data.grand_total_export)
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'docstatus'},
|
||||
{width: '25%', content: 'name'},
|
||||
{width: '25%', content: 'status'},
|
||||
{width: '35%', content: 'grand_total_export', css: {'text-align': 'right'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right'}}
|
||||
],
|
||||
});
|
||||
|
||||
cur_frm.cscript.render_list(doc, doctype, parent, ListView);
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.make_si_list = function(parent, doc) {
|
||||
var ListView = wn.views.ListView.extend({
|
||||
init: function(doclistview) {
|
||||
this._super(doclistview);
|
||||
this.fields = this.fields.concat([
|
||||
"ifnull(`tabSales Invoice`.outstanding_amount, 0) as outstanding_amount",
|
||||
"`tabSales Invoice`.currency",
|
||||
"ifnull(`tabSales Invoice`.conversion_rate, 0) as conversion_rate",
|
||||
"ifnull(`tabSales Invoice`.grand_total_export, 0) as grand_total_export",
|
||||
|
||||
]);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if (data.outstanding_amount) {
|
||||
data.outstanding_amount = data.currency + " " +
|
||||
fmt_money(flt(data.outstanding_amount)/flt(data.conversion_rate)) +
|
||||
" [outstanding]";
|
||||
|
||||
} else {
|
||||
data.outstanding_amount = '';
|
||||
}
|
||||
data.grand_total_export = data.currency + " " + fmt_money(data.grand_total_export);
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'docstatus'},
|
||||
{width: '25%', content: 'name'},
|
||||
{width: '25%', content: 'outstanding_amount',
|
||||
css: {'text-align': 'right', 'color': '#777'}},
|
||||
{width: '35%', content: 'grand_total_export', css: {'text-align': 'right'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right'}}
|
||||
],
|
||||
});
|
||||
|
||||
cur_frm.cscript.render_list(doc, 'Sales Invoice', parent, ListView);
|
||||
}
|
||||
288
selling/doctype/customer/customer.py
Normal file
288
selling/doctype/customer/customer.py
Normal file
@@ -0,0 +1,288 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import cstr, date_diff, flt, formatdate, get_defaults, getdate, has_common, now, nowdate, replace_newlines, sendmail, set_default, user_format, validate_email_add
|
||||
from webnotes.model.doc import Document, make_autoname
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes import msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
# ******************************************************* autoname ***********************************************************
|
||||
def autoname(self):
|
||||
cust_master_name = get_defaults().get('cust_master_name')
|
||||
if cust_master_name == 'Customer Name':
|
||||
# filter out bad characters in name
|
||||
#cust = self.doc.customer_name.replace('&','and').replace('.','').replace("'",'').replace('"','').replace(',','').replace('`','')
|
||||
cust = self.doc.customer_name
|
||||
|
||||
supp = sql("select name from `tabSupplier` where name = %s", (cust))
|
||||
supp = supp and supp[0][0] or ''
|
||||
if supp:
|
||||
msgprint("You already have a Supplier with same name")
|
||||
raise Exception("You already have a Supplier with same name")
|
||||
else:
|
||||
self.doc.name = cust
|
||||
else:
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# ******************************************************* triggers ***********************************************************
|
||||
# ----------------
|
||||
# get company abbr
|
||||
# -----------------
|
||||
def get_company_abbr(self):
|
||||
return get_value('Company', self.doc.company, 'abbr')
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------
|
||||
# get parent account(i.e receivables group from company where default account head need to be created)
|
||||
# -----------------------------------------------------------------------------------------------------
|
||||
def get_receivables_group(self):
|
||||
g = sql("select receivables_group from tabCompany where name=%s", self.doc.company)
|
||||
g = g and g[0][0] or ''
|
||||
if not g:
|
||||
msgprint("Update Company master, assign a default group for Receivables")
|
||||
raise Exception
|
||||
return g
|
||||
|
||||
# ******************************************************* validate *********************************************************
|
||||
# ----------------
|
||||
# validate values
|
||||
# ----------------
|
||||
def validate_values(self):
|
||||
# Master name by naming series -> Series field mandatory
|
||||
if get_defaults().get('cust_master_name') == 'Naming Series' and not self.doc.naming_series:
|
||||
msgprint("Series is Mandatory.")
|
||||
raise Exception
|
||||
|
||||
# ---------
|
||||
# validate
|
||||
# ---------
|
||||
def validate(self):
|
||||
self.validate_values()
|
||||
|
||||
# ******************************************************* on update *********************************************************
|
||||
# ------------------------
|
||||
# create customer address
|
||||
# ------------------------
|
||||
def create_customer_address(self):
|
||||
addr_flds = [self.doc.address_line1, self.doc.address_line2, self.doc.city, self.doc.state, self.doc.country, self.doc.pincode]
|
||||
address_line = "\n".join(filter(lambda x : (x!='' and x!=None),addr_flds))
|
||||
|
||||
if self.doc.phone_1:
|
||||
address_line = address_line + "\n" + "Phone: " + cstr(self.doc.phone_1)
|
||||
if self.doc.email_id:
|
||||
address_line = address_line + "\n" + "E-mail: " + cstr(self.doc.email_id)
|
||||
set(self.doc,'address', address_line)
|
||||
|
||||
telephone = "(O): " + cstr(self.doc.phone_1) +"\n"+ cstr(self.doc.phone_2) + "\n" + "(M): " + "\n" + "(fax): " + cstr(self.doc.fax_1)
|
||||
set(self.doc,'telephone',telephone)
|
||||
|
||||
|
||||
# ------------------------------------
|
||||
# create primary contact for customer
|
||||
# ------------------------------------
|
||||
def create_p_contact(self,nm,phn_no,email_id,mob_no,fax,cont_addr):
|
||||
c1 = Document('Contact')
|
||||
c1.first_name = nm
|
||||
c1.contact_name = nm
|
||||
c1.contact_no = phn_no
|
||||
c1.email_id = email_id
|
||||
c1.mobile_no = mob_no
|
||||
c1.fax = fax
|
||||
c1.contact_address = cont_addr
|
||||
c1.is_primary_contact = 'Yes'
|
||||
c1.is_customer =1
|
||||
c1.customer = self.doc.name
|
||||
c1.customer_name = self.doc.customer_name
|
||||
c1.customer_address = self.doc.address
|
||||
c1.customer_group = self.doc.customer_group
|
||||
c1.save(1)
|
||||
|
||||
|
||||
# ------------------------
|
||||
# create customer contact
|
||||
# ------------------------
|
||||
def create_customer_contact(self):
|
||||
contact = sql("select distinct name from `tabContact` where customer_name=%s", (self.doc.customer_name))
|
||||
contact = contact and contact[0][0] or ''
|
||||
if not contact:
|
||||
# create primary contact for individual customer
|
||||
if self.doc.customer_type == 'Individual':
|
||||
self.create_p_contact(self.doc.customer_name,self.doc.phone_1,self.doc.email_id,'',self.doc.fax_1,self.doc.address)
|
||||
|
||||
# create primary contact for lead
|
||||
elif self.doc.lead_name:
|
||||
c_detail = sql("select lead_name, company_name, contact_no, mobile_no, email_id, fax, address from `tabLead` where name =%s", self.doc.lead_name, as_dict=1)
|
||||
self.create_p_contact(c_detail and c_detail[0]['lead_name'] or '', c_detail and c_detail[0]['contact_no'] or '', c_detail and c_detail[0]['email_id'] or '', c_detail and c_detail[0]['mobile_no'] or '', c_detail and c_detail[0]['fax'] or '', c_detail and c_detail[0]['address'] or '')
|
||||
|
||||
|
||||
# -------------------
|
||||
# update lead status
|
||||
# -------------------
|
||||
def update_lead_status(self):
|
||||
if self.doc.lead_name:
|
||||
sql("update `tabLead` set status='Converted' where name = %s", self.doc.lead_name)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# create accont head - in tree under receivables_group of selected company
|
||||
# -------------------------------------------------------------------------
|
||||
def create_account_head(self):
|
||||
if self.doc.company :
|
||||
abbr = self.get_company_abbr()
|
||||
if not sql("select name from tabAccount where name=%s", (self.doc.name + " - " + abbr)):
|
||||
parent_account = self.get_receivables_group()
|
||||
arg = {'account_name':self.doc.name,'parent_account': parent_account, 'group_or_ledger':'Ledger', 'company':self.doc.company,'account_type':'','tax_rate':'0','master_type':'Customer','master_name':self.doc.name,'address':self.doc.address}
|
||||
# create
|
||||
ac = get_obj('GL Control').add_ac(cstr(arg))
|
||||
msgprint("Account Head created for "+ac)
|
||||
else :
|
||||
msgprint("Please Select Company under which you want to create account head")
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# update credit days and limit in account
|
||||
# ----------------------------------------
|
||||
def update_credit_days_limit(self):
|
||||
sql("update tabAccount set credit_days = '%s', credit_limit = '%s' where name = '%s'" % (self.doc.credit_days, self.doc.credit_limit, self.doc.name + " - " + self.get_company_abbr()))
|
||||
|
||||
|
||||
#create address and contact from lead
|
||||
def create_lead_address_contact(self):
|
||||
if self.doc.lead_name:
|
||||
details = sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, phone, mobile_no, fax, email_id from `tabLead` where name = '%s'" %(self.doc.lead_name), as_dict = 1)
|
||||
d = Document('Address')
|
||||
d.address_line1 = details[0]['address_line1']
|
||||
d.address_line2 = details[0]['address_line2']
|
||||
d.city = details[0]['city']
|
||||
d.country = details[0]['country']
|
||||
d.pincode = details[0]['pincode']
|
||||
d.state = details[0]['state']
|
||||
d.fax = details[0]['fax']
|
||||
d.email_id = details[0]['email_id']
|
||||
d.phone = details[0]['phone']
|
||||
d.customer = self.doc.name
|
||||
d.customer_name = self.doc.customer_name
|
||||
d.is_primary_address = 1
|
||||
d.address_type = 'Office'
|
||||
try:
|
||||
d.save(1)
|
||||
except NameError, e:
|
||||
pass
|
||||
|
||||
c = Document('Contact')
|
||||
c.first_name = details[0]['lead_name']
|
||||
c.email_id = details[0]['email_id']
|
||||
c.phone = details[0]['phone']
|
||||
c.mobile_no = details[0]['mobile_no']
|
||||
c.customer = self.doc.name
|
||||
c.customer_name = self.doc.customer_name
|
||||
c.is_primary_contact = 1
|
||||
try:
|
||||
c.save(1)
|
||||
except NameError, e:
|
||||
pass
|
||||
|
||||
# ----------
|
||||
# on update
|
||||
# ----------
|
||||
def on_update(self):
|
||||
# create customer addr
|
||||
#self.create_customer_address()
|
||||
# create customer contact
|
||||
#self.create_customer_contact()
|
||||
# update lead status
|
||||
self.update_lead_status()
|
||||
# create account head
|
||||
self.create_account_head()
|
||||
# update credit days and limit in account
|
||||
self.update_credit_days_limit()
|
||||
#create address and contact from lead
|
||||
self.create_lead_address_contact()
|
||||
|
||||
def delete_customer_address(self):
|
||||
for rec in sql("select * from `tabAddress` where customer='%s'" %(self.doc.name), as_dict=1):
|
||||
sql("delete from `tabAddress` where name=%s",(rec['name']))
|
||||
|
||||
def delete_customer_contact(self):
|
||||
for rec in sql("select * from `tabContact` where customer='%s'" %(self.doc.name), as_dict=1):
|
||||
sql("delete from `tabContact` where name=%s",(rec['name']))
|
||||
|
||||
def delete_customer_communication(self):
|
||||
webnotes.conn.sql("""\
|
||||
delete from `tabCommunication`
|
||||
where customer = %s and supplier is null""", self.doc.name)
|
||||
|
||||
def delete_customer_account(self):
|
||||
"""delete customer's ledger if exist and check balance before deletion"""
|
||||
acc = sql("select name from `tabAccount` where master_type = 'Customer' \
|
||||
and master_name = %s and docstatus < 2", self.doc.name)
|
||||
if acc:
|
||||
from webnotes.model import delete_doc
|
||||
delete_doc('Account', acc[0][0])
|
||||
|
||||
def on_trash(self):
|
||||
self.delete_customer_address()
|
||||
self.delete_customer_contact()
|
||||
self.delete_customer_communication()
|
||||
self.delete_customer_account()
|
||||
if self.doc.lead_name:
|
||||
sql("update `tabLead` set status='Interested' where name=%s",self.doc.lead_name)
|
||||
|
||||
# on rename
|
||||
# ---------
|
||||
def on_rename(self,newdn,olddn):
|
||||
#update customer_name if not naming series
|
||||
if get_defaults().get('cust_master_name') == 'Customer Name':
|
||||
update_fields = [
|
||||
('Customer', 'name'),
|
||||
('Address', 'customer'),
|
||||
('Contact', 'customer'),
|
||||
('Customer Issue', 'customer'),
|
||||
('Delivery Note', 'customer'),
|
||||
('Opportunity', 'customer'),
|
||||
('Installation Note', 'customer'),
|
||||
('Maintenance Schedule', 'customer'),
|
||||
('Maintenance Visit', 'customer'),
|
||||
('Project', 'customer'),
|
||||
('Quotation', 'customer'),
|
||||
('Sales Invoice', 'customer'),
|
||||
('Sales Order', 'customer'),
|
||||
('Serial No', 'customer'),
|
||||
('Shipping Address', 'customer'),
|
||||
('Stock Entry', 'customer'),
|
||||
('Support Ticket', 'customer'),
|
||||
('Task', 'customer')]
|
||||
for rec in update_fields:
|
||||
sql("update `tab%s` set customer_name = '%s' where %s = '%s'" %(rec[0],newdn,rec[1],olddn))
|
||||
|
||||
#update master_name in doctype account
|
||||
sql("update `tabAccount` set master_name = '%s', master_type = 'Customer' where master_name = '%s'" %(newdn,olddn))
|
||||
534
selling/doctype/customer/customer.txt
Normal file
534
selling/doctype/customer/customer.txt
Normal file
@@ -0,0 +1,534 @@
|
||||
# DocType, Customer
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-07-18 20:34:41',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-09-17 11:31:55',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1330501485',
|
||||
'allow_print': 0,
|
||||
'allow_trash': 1,
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
u'doctype': u'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
u'name': u'__common__',
|
||||
'search_fields': u'customer_name,customer_group,country,territory',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'eval:"%(customer_name)s"=="%(name)s" ? "" : "%(customer_name)s"',
|
||||
'tag_fields': u'customer_group,customer_type',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Customer',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Customer',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Customer
|
||||
{
|
||||
u'doctype': u'DocType',
|
||||
u'name': u'Customer'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Note: You Can Manage Multiple Address or Contacts via Addresses & Contacts',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'basic_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Basic Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Name',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'customer_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Customer Type',
|
||||
'oldfieldname': u'customer_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nCompany\nIndividual',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Series',
|
||||
'no_copy': 1,
|
||||
'options': u'\nCUST\nCUSTMUM',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Fetch lead which will be converted into customer.',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'lead_name',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Lead Ref',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'lead_name',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Lead',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="#!Sales Browser/Customer Group">To manage Customer Groups, click here</a>',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Group',
|
||||
'oldfieldname': u'customer_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer Group',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="#!Sales Browser/Territory">To manage Territory, click here</a>',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Territory',
|
||||
'oldfieldname': u'territory',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_contacts',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Address & Contacts',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_desc',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Address Desc',
|
||||
'options': u'<em>Addresses will appear only when you save the customer</em>',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Address HTML',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_desc',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Contact Desc',
|
||||
'options': u'<em>Contact Details will appear only when you save the customer</em>',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Contact HTML',
|
||||
'oldfieldtype': u'HTML',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Communication History',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Communication HTML',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'more_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'More Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'To create an Account Head under a different company, select the company and save customer.',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_price_list',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Default Price List',
|
||||
'options': u'Price List',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'This currency will get fetched in Sales transactions of this customer',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_currency',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Default Currency',
|
||||
'no_copy': 1,
|
||||
'options': u'link:Currency',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u"Your Customer's TAX registration numbers (if applicable) or any general information",
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_details',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Customer Details',
|
||||
'oldfieldname': u'customer_details',
|
||||
'oldfieldtype': u'Code',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'credit_days',
|
||||
'fieldtype': u'Int',
|
||||
'label': u'Credit Days',
|
||||
'oldfieldname': u'credit_days',
|
||||
'oldfieldtype': u'Int',
|
||||
'permlevel': 2
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'credit_limit',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Credit Limit',
|
||||
'oldfieldname': u'credit_limit',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 2
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'website',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Website',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'sales_team_section_break',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Sales Team',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_sales_partner',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Default Sales Partner',
|
||||
'oldfieldname': u'default_sales_partner',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Sales Partner',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_commission_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Default Commission Rate',
|
||||
'oldfieldname': u'default_commission_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'sales_team',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Sales Team Details',
|
||||
'oldfieldname': u'sales_team',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Sales Team',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'transaction_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Transaction History',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'history_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'History HTML',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'oldfieldname': u'trash_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Master Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Accounts Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'Accounts Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'System Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'All'
|
||||
}
|
||||
]
|
||||
28
selling/doctype/customer/customer_list.js
Normal file
28
selling/doctype/customer/customer_list.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// render
|
||||
wn.doclistviews['Customer'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabCustomer`.customer_name",
|
||||
"`tabCustomer`.territory",
|
||||
]);
|
||||
this.show_hide_check_column();
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
data.customer_name = repl("<a href=\"#!Form/Customer/%(name)s\">%(customer_name)s</a>",
|
||||
data);
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content:'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '50%', content:'customer_name'},
|
||||
{width: '10%', content:'tags'},
|
||||
{width: '20%', content:'territory',
|
||||
css: {'color': '#aaa'}},
|
||||
{width: '12%', content:'modified',
|
||||
css: {'text-align': 'right', 'color':'#777'}}
|
||||
],
|
||||
});
|
||||
1
selling/doctype/industry_type/__init__.py
Normal file
1
selling/doctype/industry_type/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
26
selling/doctype/industry_type/industry_type.js
Normal file
26
selling/doctype/industry_type/industry_type.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
//--------- ONLOAD -------------
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
85
selling/doctype/industry_type/industry_type.txt
Normal file
85
selling/doctype/industry_type/industry_type.txt
Normal file
@@ -0,0 +1,85 @@
|
||||
# DocType, Industry Type
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:09',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:09',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'harshada@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'field:industry',
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 4
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'industry',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Industry',
|
||||
'name': '__common__',
|
||||
'oldfieldname': u'industry',
|
||||
'oldfieldtype': u'Data',
|
||||
'parent': u'Industry Type',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Industry Type',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Industry Type
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Industry Type'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/installation_note/__init__.py
Normal file
1
selling/doctype/installation_note/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
85
selling/doctype/installation_note/installation_note.js
Normal file
85
selling/doctype/installation_note/installation_note.js
Normal file
@@ -0,0 +1,85 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cur_frm.cscript.tname = "Installation Note Item";
|
||||
cur_frm.cscript.fname = "installed_item_details";
|
||||
|
||||
cur_frm.cscript.onload = function(doc, dt, dn) {
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
||||
if(doc.__islocal){
|
||||
set_multiple(dt,dn,{inst_date:get_today()});
|
||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
if (doc.customer) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['delivery_note_no'].get_query = function(doc) {
|
||||
doc = locals[this.doctype][this.docname];
|
||||
var cond = '';
|
||||
if(doc.customer) {
|
||||
cond = '`tabDelivery Note`.customer = "'+doc.customer+'" AND';
|
||||
}
|
||||
return repl('SELECT DISTINCT `tabDelivery Note`.name, `tabDelivery Note`.customer_name FROM `tabDelivery Note`, `tabDelivery Note Item` WHERE `tabDelivery Note`.company = "%(company)s" AND `tabDelivery Note`.docstatus = 1 AND ifnull(`tabDelivery Note`.per_installed,0) < 100 AND %(cond)s `tabDelivery Note`.name LIKE "%s" ORDER BY `tabDelivery Note`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||
var callback = function(r,rt) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
cur_frm.refresh();
|
||||
}
|
||||
get_server_fields('pull_delivery_note_details','','',doc, dt, dn,1,callback);
|
||||
}
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
cur_frm.refresh();
|
||||
}
|
||||
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback);
|
||||
if(doc.customer) unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
213
selling/doctype/installation_note/installation_note.py
Normal file
213
selling/doctype/installation_note/installation_note.py
Normal file
@@ -0,0 +1,213 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.tname = 'Installation Note Item'
|
||||
self.fname = 'installed_item_details'
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
#fetch delivery note details
|
||||
#====================================
|
||||
def pull_delivery_note_details(self):
|
||||
self.validate_prev_docname()
|
||||
self.doclist = get_obj('DocType Mapper', 'Delivery Note-Installation Note').dt_map('Delivery Note', 'Installation Note', self.doc.delivery_note_no, self.doc, self.doclist, "[['Delivery Note', 'Installation Note'],['Delivery Note Item', 'Installation Note Item']]")
|
||||
|
||||
# Validates that Delivery Note is not pulled twice
|
||||
#============================================
|
||||
def validate_prev_docname(self):
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
if self.doc.delivery_note_no == d.prevdoc_docname:
|
||||
msgprint(cstr(self.doc.delivery_note_no) + " delivery note details have already been pulled. ")
|
||||
raise Exception, "Validation Error. "
|
||||
|
||||
#Fiscal Year Validation
|
||||
#================================
|
||||
def validate_fiscal_year(self):
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.inst_date,'Installation Date')
|
||||
|
||||
# Validate Mandatory
|
||||
#===============================
|
||||
def validate_mandatory(self):
|
||||
# Amendment Date
|
||||
if self.doc.amended_from and not self.doc.amendment_date:
|
||||
msgprint("Please Enter Amendment Date")
|
||||
raise Exception, "Validation Error. "
|
||||
|
||||
# Validate values with reference document
|
||||
#----------------------------------------
|
||||
def validate_reference_value(self):
|
||||
get_obj('DocType Mapper', 'Delivery Note-Installation Note', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||
|
||||
#check if serial no added
|
||||
#-----------------------------
|
||||
def is_serial_no_added(self,item_code,serial_no):
|
||||
ar_required = sql("select has_serial_no from tabItem where name = '%s'" % item_code)
|
||||
ar_required = ar_required and ar_required[0][0] or ''
|
||||
if ar_required == 'Yes' and not serial_no:
|
||||
msgprint("Serial No is mandatory for item: "+ item_code)
|
||||
raise Exception
|
||||
elif ar_required != 'Yes' and cstr(serial_no).strip():
|
||||
msgprint("If serial no required, please select 'Yes' in 'Has Serial No' in Item :"+item_code)
|
||||
raise Exception
|
||||
|
||||
#check if serial no exist in system
|
||||
#-------------------------------------
|
||||
def is_serial_no_exist(self, item_code, serial_no):
|
||||
for x in serial_no:
|
||||
chk = sql("select name from `tabSerial No` where name =%s", x)
|
||||
if not chk:
|
||||
msgprint("Serial No "+x+" does not exist in the system")
|
||||
raise Exception
|
||||
|
||||
#check if serial no already installed
|
||||
#------------------------------------------
|
||||
def is_serial_no_installed(self,cur_s_no,item_code):
|
||||
for x in cur_s_no:
|
||||
status = sql("select status from `tabSerial No` where name = %s", x)
|
||||
status = status and status[0][0] or ''
|
||||
|
||||
if status == 'Installed':
|
||||
msgprint("Item "+item_code+" with serial no. "+x+" already installed")
|
||||
raise Exception, "Validation Error."
|
||||
|
||||
#get list of serial no from previous_doc
|
||||
#----------------------------------------------
|
||||
def get_prevdoc_serial_no(self, prevdoc_detail_docname, prevdoc_docname):
|
||||
from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list
|
||||
|
||||
res = sql("select serial_no from `tabDelivery Note Item` where name = '%s' and parent ='%s'" % (prevdoc_detail_docname, prevdoc_docname))
|
||||
return get_sr_no_list(res[0][0])
|
||||
|
||||
#check if all serial nos from current record exist in resp delivery note
|
||||
#---------------------------------------------------------------------------------
|
||||
def is_serial_no_match(self, cur_s_no, prevdoc_s_no, prevdoc_docname):
|
||||
for x in cur_s_no:
|
||||
if not(x in prevdoc_s_no):
|
||||
msgprint("Serial No. "+x+" not present in the Delivery Note "+prevdoc_docname, raise_exception = 1)
|
||||
raise Exception, "Validation Error."
|
||||
|
||||
#validate serial number
|
||||
#----------------------------------------
|
||||
def validate_serial_no(self):
|
||||
cur_s_no, prevdoc_s_no, sr_list = [], [], []
|
||||
from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list
|
||||
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
self.is_serial_no_added(d.item_code, d.serial_no)
|
||||
|
||||
if d.serial_no:
|
||||
|
||||
sr_list = get_sr_no_list(d.serial_no, d.qty, d.item_code)
|
||||
self.is_serial_no_exist(d.item_code, sr_list)
|
||||
|
||||
prevdoc_s_no = self.get_prevdoc_serial_no(d.prevdoc_detail_docname, d.prevdoc_docname)
|
||||
if prevdoc_s_no:
|
||||
self.is_serial_no_match(sr_list, prevdoc_s_no, d.prevdoc_docname)
|
||||
|
||||
self.is_serial_no_installed(sr_list, d.item_code)
|
||||
return sr_list
|
||||
|
||||
#validate installation date
|
||||
#-------------------------------
|
||||
def validate_installation_date(self):
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
if d.prevdoc_docname:
|
||||
d_date = sql("select posting_date from `tabDelivery Note` where name=%s", d.prevdoc_docname)
|
||||
d_date = d_date and d_date[0][0] or ''
|
||||
|
||||
if d_date > getdate(self.doc.inst_date):
|
||||
msgprint("Installation Date can not be before Delivery Date "+cstr(d_date)+" for item "+d.item_code)
|
||||
raise Exception
|
||||
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.validate_installation_date()
|
||||
self.check_item_table()
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.get_prevdoc_date(self)
|
||||
self.validate_mandatory()
|
||||
self.validate_reference_value()
|
||||
|
||||
def check_item_table(self):
|
||||
if not(getlist(self.doclist, 'installed_item_details')):
|
||||
msgprint("Please fetch items from Delivery Note selected")
|
||||
raise Exception
|
||||
|
||||
def on_update(self):
|
||||
set(self.doc, 'status', 'Draft')
|
||||
|
||||
def on_submit(self):
|
||||
valid_lst = []
|
||||
valid_lst = self.validate_serial_no()
|
||||
|
||||
get_obj("Sales Common").update_prevdoc_detail(1,self)
|
||||
|
||||
for x in valid_lst:
|
||||
wp = sql("select warranty_period from `tabSerial No` where name = '%s'"% x)
|
||||
wp = wp and wp[0][0] or 0
|
||||
if wp:
|
||||
sql("update `tabSerial No` set maintenance_status = 'Under Warranty' where name = '%s'" % x)
|
||||
|
||||
sql("update `tabSerial No` set status = 'Installed' where name = '%s'" % x)
|
||||
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
cur_s_no = []
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.update_prevdoc_detail(0,self)
|
||||
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
if d.serial_no:
|
||||
#get current list of serial no
|
||||
cur_serial_no = d.serial_no.replace(' ', '')
|
||||
cur_s_no = cur_serial_no.split(',')
|
||||
|
||||
for x in cur_s_no:
|
||||
sql("update `tabSerial No` set status = 'Delivered' where name = '%s'" % x)
|
||||
|
||||
set(self.doc, 'status', 'Cancelled')
|
||||
453
selling/doctype/installation_note/installation_note.txt
Normal file
453
selling/doctype/installation_note/installation_note.txt
Normal file
@@ -0,0 +1,453 @@
|
||||
# DocType, Installation Note
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:09',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 18:48:02',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1306480044',
|
||||
'autoname': u'IN/.####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'is_submittable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'At %(customer_name)s on %(inst_date)s',
|
||||
'version': 98
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Installation Note',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Installation Note',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Installation Note
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Installation Note'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'installation_note',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Installation Note',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Series',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'naming_series',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nIN',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer',
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer Address',
|
||||
'options': u'Address',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_person',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Contact Person',
|
||||
'options': u'Contact',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Name',
|
||||
'oldfieldname': u'customer_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'address_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Address',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Contact',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_mobile',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Mobile No',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_email',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Contact Email',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Territory',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_group',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer Group',
|
||||
'options': u'Customer Group',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'inst_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Installation Date',
|
||||
'oldfieldname': u'inst_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'inst_time',
|
||||
'fieldtype': u'Time',
|
||||
'label': u'Installation Time',
|
||||
'oldfieldname': u'inst_time',
|
||||
'oldfieldtype': u'Time',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'Draft',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'status',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Status',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'Draft\nSubmitted\nCancelled',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Select the relevant company name if you have multiple companies.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Company',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amended_from',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Amended From',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amended_from',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The date at which current entry is corrected in the system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amendment_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 1,
|
||||
'label': u'Amendment Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amendment_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'remarks',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Remarks',
|
||||
'oldfieldname': u'remarks',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'cancel_reason',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Cancel Reason',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'cancel_reason',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Item Details',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'options': u'Simple',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_note_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Delivery Note No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'delivery_note_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Delivery Note',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'get_items',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 0,
|
||||
'label': u'Get Items',
|
||||
'oldfieldtype': u'Button',
|
||||
'options': u'pull_delivery_note_details',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'installed_item_details',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Installation Note Item',
|
||||
'oldfieldname': u'installed_item_details',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Installation Note Item',
|
||||
'permlevel': 0
|
||||
}
|
||||
]
|
||||
1
selling/doctype/installation_note_item/__init__.py
Normal file
1
selling/doctype/installation_note_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,153 @@
|
||||
# DocType, Installation Note Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:10',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:10',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'IID/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 25
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Installation Note Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Installation Note Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Installation Note Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 0,
|
||||
'label': u'Delivery Date',
|
||||
'oldfieldname': u'prevdoc_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Serial No',
|
||||
'oldfieldname': u'serial_no',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'width': u'180px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_detail_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Against Document Detail No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_detail_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Against Document No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_doctype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Document Type',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_doctype',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Installed Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
}
|
||||
]
|
||||
1
selling/doctype/lead/__init__.py
Normal file
1
selling/doctype/lead/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
143
selling/doctype/lead/lead.js
Normal file
143
selling/doctype/lead/lead.js
Normal file
@@ -0,0 +1,143 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Module CRM
|
||||
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(user =='Guest'){
|
||||
hide_field(['status', 'naming_series', 'order_lost_reason',
|
||||
'customer', 'rating', 'fax', 'website', 'territory',
|
||||
'address_line1', 'address_line2', 'city', 'state',
|
||||
'country', 'pincode', 'address', 'lead_owner', 'market_segment',
|
||||
'industry', 'campaign_name', 'interested_in', 'company',
|
||||
'fiscal_year', 'contact_by', 'contact_date', 'last_contact_date',
|
||||
'contact_date_ref', 'to_discuss', 'more_info', 'follow_up',
|
||||
'communication_history', 'cc_to', 'subject', 'message', 'lead_attachment_detail',
|
||||
'Create Customer', 'Create Opportunity', 'transaction_date', 'type', 'source']);
|
||||
doc.source = 'Website';
|
||||
}
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Open'});
|
||||
|
||||
if (!doc.date){
|
||||
doc.date = date.obj_to_str(new Date());
|
||||
}
|
||||
// set naming series
|
||||
if(user=='Guest') doc.naming_series = 'WebLead';
|
||||
|
||||
cur_frm.add_fetch('customer', 'customer_name', 'company_name');
|
||||
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh_custom_buttons = function() {
|
||||
cur_frm.clear_custom_buttons();
|
||||
if(!doc.__islocal && !in_list(['Converted', 'Lead Lost'], doc.status)) {
|
||||
if (doc.source != 'Existing Customer') {
|
||||
cur_frm.add_custom_button('Create Customer',
|
||||
cur_frm.cscript['Create Customer']);
|
||||
}
|
||||
cur_frm.add_custom_button('Create Opportunity',
|
||||
cur_frm.cscript['Create Opportunity']);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
// custom buttons
|
||||
//---------------
|
||||
cur_frm.cscript.refresh_custom_buttons();
|
||||
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
if (!doc.__islocal) cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
// Client Side Triggers
|
||||
// ===========================================================
|
||||
// ************ Status ******************
|
||||
cur_frm.cscript.status = function(doc, cdt, cdn){
|
||||
cur_frm.cscript.refresh(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
//Trigger in Item Table
|
||||
//===================================
|
||||
cur_frm.cscript.item_code=function(doc,cdt,cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.item_code) { get_server_fields('get_item_detail',d.item_code,'lead_item_detail',doc,cdt,cdn,1);}
|
||||
}
|
||||
|
||||
// Create New Customer
|
||||
// ===============================================================
|
||||
cur_frm.cscript['Create Customer'] = function(){
|
||||
var doc = cur_frm.doc;
|
||||
$c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))},
|
||||
function(r,rt){
|
||||
if(r.message == 'Converted'){
|
||||
msgprint("This lead is already converted to customer");
|
||||
}
|
||||
else{
|
||||
n = createLocal("Customer");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Customer"][n]]),
|
||||
'from_doctype':'Lead',
|
||||
'to_doctype':'Customer',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Lead', 'Customer']]"
|
||||
},
|
||||
function(r,rt) {
|
||||
loaddoc("Customer", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Create New Opportunity
|
||||
// ===============================================================
|
||||
cur_frm.cscript['Create Opportunity'] = function(){
|
||||
var doc = cur_frm.doc;
|
||||
$c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))},
|
||||
function(r,rt){
|
||||
if(r.message == 'Converted'){
|
||||
msgprint("This lead is now converted to customer. Please create enquiry on behalf of customer");
|
||||
}
|
||||
else{
|
||||
n = createLocal("Opportunity");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Opportunity"][n]]),
|
||||
'from_doctype':'Lead',
|
||||
'to_doctype':'Opportunity',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Lead', 'Opportunity']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Opportunity", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
}
|
||||
147
selling/doctype/lead/lead.py
Normal file
147
selling/doctype/lead/lead.py
Normal file
@@ -0,0 +1,147 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
#check status of lead
|
||||
#------------------------
|
||||
def check_status(self):
|
||||
chk = sql("select status from `tabLead` where name=%s", self.doc.name)
|
||||
chk = chk and chk[0][0] or ''
|
||||
return cstr(chk)
|
||||
|
||||
|
||||
# Get item detail (will be removed later)
|
||||
#=======================================
|
||||
def get_item_detail(self,item_code):
|
||||
it=sql("select item_name,brand,item_group,description,stock_uom from `tabItem` where name='%s'"%item_code)
|
||||
if it:
|
||||
ret = {
|
||||
'item_name' : it and it[0][0] or '',
|
||||
'brand' : it and it[0][1] or '',
|
||||
'item_group' : it and it[0][2] or '',
|
||||
'description': it and it[0][3] or '',
|
||||
'uom' : it and it[0][4] or ''
|
||||
}
|
||||
return ret
|
||||
|
||||
def validate(self):
|
||||
import string
|
||||
if self.doc.status == 'Lead Lost' and not self.doc.order_lost_reason:
|
||||
msgprint("Please Enter Lost Reason under More Info section")
|
||||
raise Exception
|
||||
|
||||
if self.doc.source == 'Campaign' and not self.doc.campaign_name and session['user'] != 'Guest':
|
||||
msgprint("Please specify campaign name")
|
||||
raise Exception
|
||||
|
||||
if self.doc.email_id:
|
||||
if not validate_email_add(self.doc.email_id):
|
||||
msgprint('Please enter valid email id.')
|
||||
raise Exception
|
||||
|
||||
|
||||
def on_update(self):
|
||||
if self.doc.contact_by:
|
||||
self.add_calendar_event()
|
||||
|
||||
if not self.doc.naming_series:
|
||||
if session['user'] == 'Guest':
|
||||
import webnotes.model.doctype
|
||||
docfield = webnotes.model.doctype.get('Lead')
|
||||
series = [d.options for d in docfield if d.doctype == 'DocField' and d.fieldname == 'naming_series']
|
||||
if series:
|
||||
sr = series[0].split("\n")
|
||||
set(self.doc, 'naming_series', sr[0])
|
||||
else:
|
||||
msgprint("Please specify naming series")
|
||||
raise Exception
|
||||
|
||||
# Add to Calendar
|
||||
# ===========================================================================
|
||||
def add_calendar_event(self):
|
||||
# delete any earlier event by this lead
|
||||
sql("delete from tabEvent where ref_type='Lead' and ref_name=%s", self.doc.name)
|
||||
|
||||
in_calendar_of = self.doc.lead_owner
|
||||
|
||||
# get profile (id) if exists for contact_by
|
||||
email_id = webnotes.conn.get_value('Sales Person', self.doc.contact_by, 'email_id')
|
||||
if webnotes.conn.exists('Profile', email_id):
|
||||
in_calendar_of = email_id
|
||||
|
||||
ev = Document('Event')
|
||||
ev.owner = in_calendar_of
|
||||
ev.description = 'Contact ' + cstr(self.doc.lead_name) + '.By : ' + cstr(self.doc.contact_by) + '.To Discuss : ' + cstr(self.doc.remark)
|
||||
ev.event_date = self.doc.contact_date
|
||||
ev.event_hour = '10:00'
|
||||
ev.event_type = 'Private'
|
||||
ev.ref_type = 'Lead'
|
||||
ev.ref_name = self.doc.name
|
||||
ev.save(1)
|
||||
|
||||
def add_in_follow_up(self,message,type):
|
||||
import datetime
|
||||
child = addchild( self.doc, 'follow_up', 'Communication Log', 1, self.doclist)
|
||||
child.date = datetime.datetime.now().date().strftime('%Y-%m-%d')
|
||||
child.notes = message
|
||||
child.follow_up_type = type
|
||||
child.save()
|
||||
|
||||
#-------------------SMS----------------------------------------------
|
||||
def send_sms(self):
|
||||
if not self.doc.sms_message or not self.doc.mobile_no:
|
||||
msgprint("Please enter mobile number in Basic Info Section and message in SMS Section ")
|
||||
raise Exception
|
||||
else:
|
||||
receiver_list = []
|
||||
if self.doc.mobile_no:
|
||||
receiver_list.append(self.doc.mobile_no)
|
||||
for d in getlist(self.doclist,'lead_sms_detail'):
|
||||
if d.other_mobile_no:
|
||||
receiver_list.append(d.other_mobile_no)
|
||||
|
||||
if receiver_list:
|
||||
msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, self.doc.sms_message))
|
||||
# self.add_in_follow_up(self.doc.sms_message,'SMS')
|
||||
702
selling/doctype/lead/lead.txt
Normal file
702
selling/doctype/lead/lead.txt
Normal file
@@ -0,0 +1,702 @@
|
||||
# DocType, Lead
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-06-05 20:03:20',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-08-06 14:49:48',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1332222225',
|
||||
'allow_trash': 1,
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
u'doctype': u'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
u'name': u'__common__',
|
||||
'search_fields': u'lead_name,lead_owner,status',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'%(lead_name)s from %(company_name)s | To Discuss: %(to_discuss)s',
|
||||
'tag_fields': u'status,source',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Lead',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Lead',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Lead
|
||||
{
|
||||
u'doctype': u'DocType',
|
||||
u'name': u'Lead'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'basic_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Basic Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'To manage multiple series please go to Setup > Manage Series',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Naming Series',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'naming_series',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'LEAD\nLEAD/10-11/\nLEAD/MUMBAI/',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'lead_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Contact Name',
|
||||
'oldfieldname': u'lead_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Name of organization from where lead has come',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'company_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Company Name',
|
||||
'oldfieldname': u'company_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Source of the lead. If via a campaign, select "Campaign"',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'source',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Source',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'source',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nAdvertisement\nBlog\nCampaign\nCall\nCustomer\nExhibition\nSupplier\nWebsite',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.source == 'Existing Customer'",
|
||||
'description': u'Source of th',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'label': u'From Customer',
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.source == 'Campaign'",
|
||||
'description': u'Enter campaign name if the source of lead is campaign.',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'campaign_name',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'label': u'Campaign Name',
|
||||
'oldfieldname': u'campaign_name',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Campaign',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'Open',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'status',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Status',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nOpen\nAttempted to Contact\nContact in Future\nContacted\nInterested\nNot interested\nLead Lost\nConverted',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'type',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Lead Type',
|
||||
'oldfieldname': u'type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nClient\nChannel Partner\nConsultant',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'remark',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Remark',
|
||||
'oldfieldname': u'remark',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Communication History',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Communication HTML',
|
||||
'oldfieldname': u'follow_up',
|
||||
'oldfieldtype': u'Table',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Contact Info',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'phone',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Phone',
|
||||
'oldfieldname': u'contact_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'mobile_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Mobile No.',
|
||||
'oldfieldname': u'mobile_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'email_id',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Email Id',
|
||||
'oldfieldname': u'email_id',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'fax',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Fax',
|
||||
'oldfieldname': u'fax',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'website',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Website',
|
||||
'oldfieldname': u'website',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="javascript:cur_frm.cscript.TerritoryHelp();">To manage Territory, click here</a>',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Territory',
|
||||
'oldfieldname': u'territory',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_line1',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Address Line 1',
|
||||
'oldfieldname': u'address_line1',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_line2',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Address Line 2',
|
||||
'oldfieldname': u'address_line2',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'city',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'City',
|
||||
'oldfieldname': u'city',
|
||||
'oldfieldtype': u'Select',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'country',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Country',
|
||||
'oldfieldname': u'country',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Country',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'state',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'State',
|
||||
'oldfieldname': u'state',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'Suggest',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'pincode',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Pin Code',
|
||||
'oldfieldname': u'pincode',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'more_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'More Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'__user',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'lead_owner',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Lead Owner',
|
||||
'oldfieldname': u'lead_owner',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Profile',
|
||||
'permlevel': 0,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'market_segment',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Market Segment',
|
||||
'oldfieldname': u'market_segment',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nLower Income\nMiddle Income\nUpper Income',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'industry',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Industry',
|
||||
'oldfieldname': u'industry',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Industry Type',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'request_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Request Type',
|
||||
'oldfieldname': u'request_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nProduct Enquiry\nRequest for Information\nSuggestions\nOther',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'depends_on': u"eval:doc.status == 'Lead Lost'",
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'order_lost_reason',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'label': u'Lost Reason',
|
||||
'oldfieldname': u'order_lost_reason',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Quotation Lost Reason',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person who will contact the lead in future',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_by',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Next Contact By',
|
||||
'oldfieldname': u'contact_by',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Profile',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person will get a reminder on this date to contact the lead',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'in_filter': 1,
|
||||
'label': u'Next Contact Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
'description': u'Date on which the lead was last contacted',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'last_contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Last Contact Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'last_contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'trash_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'unsubscribed',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Unsubscribed',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'blog_subscriber',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Blog Subscriber',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Guest',
|
||||
'write': 1
|
||||
}
|
||||
]
|
||||
34
selling/doctype/lead/lead_list.js
Normal file
34
selling/doctype/lead/lead_list.js
Normal file
@@ -0,0 +1,34 @@
|
||||
wn.doclistviews['Lead'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
'tabLead.lead_name',
|
||||
'tabLead.status',
|
||||
'tabLead.source'
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'source', 'rating', 'company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(data.status=='Interested') {
|
||||
data.label_type = 'success'
|
||||
}
|
||||
else if(['Open', 'Attempted to Contact', 'Contacted', 'Contact in Future'].indexOf(data.status)!=-1) {
|
||||
data.label_type = 'info'
|
||||
}
|
||||
data.status_html = repl('<span class="label label-%(label_type)s">%(status)s</span>', data);
|
||||
data.lead_name = repl("<a href=\"#!Form/Lead/%(name)s\">%(lead_name)s</a>",
|
||||
data);
|
||||
data.lead_status = (data.rating ? ('['+data.rating+'] ') : '') + '['+data.source+']';
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '30%', content:'lead_name'},
|
||||
{width: '12%', content:'status_html'},
|
||||
{width: '38%', content:'lead_status+tags', css: {color:'#222'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
||||
]
|
||||
})
|
||||
1
selling/doctype/opportunity/__init__.py
Normal file
1
selling/doctype/opportunity/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
215
selling/doctype/opportunity/opportunity.js
Normal file
215
selling/doctype/opportunity/opportunity.js
Normal file
@@ -0,0 +1,215 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn){
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
cur_frm.clear_custom_buttons();
|
||||
if(doc.docstatus == 1) {
|
||||
cur_frm.add_custom_button('Create Quotation', cur_frm.cscript['Create Quotation']);
|
||||
cur_frm.add_custom_button('Opportunity Lost', cur_frm.cscript['Declare Opportunity Lost']);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
}
|
||||
if(!doc.__islocal) cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
// ONLOAD
|
||||
// ===============================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
if(!doc.enquiry_from) hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', 'lead_name', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']);
|
||||
if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'});
|
||||
if(!doc.date) doc.transaction_date = date.obj_to_str(new Date());
|
||||
if(!doc.company && sys_defaults.company) set_multiple(cdt,cdn,{company:sys_defaults.company});
|
||||
if(!doc.fiscal_year && sys_defaults.fiscal_year) set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year});
|
||||
|
||||
if(doc.enquiry_from) {
|
||||
if(doc.enquiry_from == 'Customer') {
|
||||
hide_field(['lead', 'lead_name']);
|
||||
}
|
||||
else if (doc.enquiry_from == 'Lead') {
|
||||
hide_field(['customer', 'customer_address', 'contact_person', 'customer_name', 'contact_display', 'customer_group']);
|
||||
}
|
||||
}
|
||||
|
||||
// setup fetch
|
||||
cur_frm.cscript.set_fetch();
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
||||
if(doc.enquiry_from == 'Lead' && doc.lead) {
|
||||
cur_frm.cscript.lead(doc,cdt,cdn);
|
||||
}
|
||||
}
|
||||
|
||||
// fetch
|
||||
// ===============================================================
|
||||
cur_frm.cscript.set_fetch = function() {
|
||||
// item
|
||||
cur_frm.add_fetch('item_code', 'item_name', 'item_name');
|
||||
cur_frm.add_fetch('item_code', 'stock_uom', 'uom');
|
||||
cur_frm.add_fetch('item_code', 'description', 'description');
|
||||
cur_frm.add_fetch('item_code', 'item_group', 'item_group');
|
||||
cur_frm.add_fetch('item_code', 'brand', 'brand');
|
||||
|
||||
// customer
|
||||
}
|
||||
|
||||
// hide - unhide fields on basis of enquiry_from lead or customer
|
||||
cur_frm.cscript.enquiry_from = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.lead_cust_show(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
// hide - unhide fields based on lead or customer
|
||||
cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){
|
||||
if(doc.enquiry_from == 'Lead'){
|
||||
unhide_field(['lead']);
|
||||
hide_field(['lead_name','customer','customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
doc.lead = doc.lead_name = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = "";
|
||||
}
|
||||
else if(doc.enquiry_from == 'Customer'){
|
||||
unhide_field(['customer']);
|
||||
hide_field(['lead','lead_name','address_display','contact_display','contact_mobile','contact_email','territory']);
|
||||
doc.lead = doc.lead_name = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = "";
|
||||
}
|
||||
}
|
||||
|
||||
// customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_default_customer_address', JSON.stringify({customer: doc.customer}),'', doc, dt, dn, 1);
|
||||
if(doc.customer) unhide_field(['customer_name','customer_address','contact_person','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
// lead
|
||||
cur_frm.fields_dict['lead'].get_query = function(doc,cdt,cdn){
|
||||
return 'SELECT `tabLead`.name, `tabLead`.lead_name FROM `tabLead` WHERE `tabLead`.%(key)s LIKE "%s" ORDER BY `tabLead`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
||||
if(doc.lead) get_server_fields('get_lead_details', doc.lead,'', doc, cdt, cdn, 1);
|
||||
if(doc.lead) unhide_field(['lead_name','address_display','contact_mobile','contact_email','territory']);
|
||||
}
|
||||
|
||||
|
||||
//item getquery
|
||||
//=======================================
|
||||
cur_frm.fields_dict['enquiry_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
||||
if (doc.enquiry_type == 'Maintenance')
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem WHERE tabItem.is_service_item="Yes" AND (ifnull(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life` > NOW() OR `tabItem`.`end_of_life`="0000-00-00") AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
else
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem WHERE tabItem.is_sales_item="Yes" AND (ifnull(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life` > NOW() OR `tabItem`.`end_of_life`="0000-00-00") AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
}
|
||||
|
||||
// Create New Quotation
|
||||
cur_frm.cscript['Create Quotation'] = function(){
|
||||
n = createLocal("Quotation");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Quotation"][n]]),
|
||||
'from_doctype':'Opportunity',
|
||||
'to_doctype':'Quotation',
|
||||
'from_docname':cur_frm.docname,
|
||||
'from_to_list':"[['Opportunity', 'Quotation'],['Opportunity Item','Quotation Item']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Quotation", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// declare enquiry lost
|
||||
//-------------------------
|
||||
cur_frm.cscript['Declare Opportunity Lost'] = function(){
|
||||
var e_lost_dialog;
|
||||
|
||||
set_e_lost_dialog = function(){
|
||||
e_lost_dialog = new Dialog(400,150,'Add Opportunity Lost Reason');
|
||||
e_lost_dialog.make_body([
|
||||
['HTML', 'Message', '<div class="comment">Please add enquiry lost reason</div>'],
|
||||
['Text', 'Opportunity Lost Reason'],
|
||||
['HTML', 'Response', '<div class = "comment" id="update_enquiry_dialog_response"></div>'],
|
||||
['HTML', 'Add Reason', '<div></div>']
|
||||
]);
|
||||
|
||||
var add_reason_btn1 = $a($i(e_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn1.innerHTML = 'Add';
|
||||
add_reason_btn1.onclick = function(){ e_lost_dialog.add(); }
|
||||
|
||||
var add_reason_btn2 = $a($i(e_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn2.innerHTML = 'Cancel';
|
||||
$y(add_reason_btn2,{marginLeft:'4px'});
|
||||
add_reason_btn2.onclick = function(){ e_lost_dialog.hide();}
|
||||
|
||||
e_lost_dialog.onshow = function() {
|
||||
e_lost_dialog.widgets['Opportunity Lost Reason'].value = '';
|
||||
$i('update_enquiry_dialog_response').innerHTML = '';
|
||||
}
|
||||
|
||||
e_lost_dialog.add = function() {
|
||||
// sending...
|
||||
$i('update_enquiry_dialog_response').innerHTML = 'Processing...';
|
||||
var arg = strip(e_lost_dialog.widgets['Opportunity Lost Reason'].value);
|
||||
var call_back = function(r,rt) {
|
||||
if(r.message == 'true'){
|
||||
$i('update_enquiry_dialog_response').innerHTML = 'Done';
|
||||
e_lost_dialog.hide();
|
||||
}
|
||||
}
|
||||
if(arg) {
|
||||
$c_obj(make_doclist(cur_frm.doc.doctype, cur_frm.doc.name),'declare_enquiry_lost',arg,call_back);
|
||||
}
|
||||
else{
|
||||
msgprint("Please add enquiry lost reason");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(!e_lost_dialog){
|
||||
set_e_lost_dialog();
|
||||
}
|
||||
e_lost_dialog.show();
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';}
|
||||
229
selling/doctype/opportunity/opportunity.py
Normal file
229
selling/doctype/opportunity/opportunity.py
Normal file
@@ -0,0 +1,229 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self,doc,doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.fname = 'enq_details'
|
||||
self.tname = 'Opportunity Item'
|
||||
|
||||
# Autoname
|
||||
# ====================================================================================================================
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.####')
|
||||
|
||||
#--------Get customer address-------
|
||||
# ====================================================================================================================
|
||||
def get_cust_address(self,name):
|
||||
details = sql("select customer_name, address, territory, customer_group from `tabCustomer` where name = '%s' and docstatus != 2" %(name), as_dict = 1)
|
||||
if details:
|
||||
ret = {
|
||||
'customer_name': details and details[0]['customer_name'] or '',
|
||||
'address' : details and details[0]['address'] or '',
|
||||
'territory' : details and details[0]['territory'] or '',
|
||||
'customer_group' : details and details[0]['customer_group'] or ''
|
||||
}
|
||||
# ********** get primary contact details (this is done separately coz. , in case there is no primary contact thn it would not be able to fetch customer details in case of join query)
|
||||
|
||||
contact_det = sql("select contact_name, contact_no, email_id from `tabContact` where customer = '%s' and is_customer = 1 and is_primary_contact = 'Yes' and docstatus != 2" %(name), as_dict = 1)
|
||||
|
||||
|
||||
ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
|
||||
ret['contact_no'] = contact_det and contact_det[0]['contact_no'] or ''
|
||||
ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''
|
||||
|
||||
return ret
|
||||
else:
|
||||
msgprint("Customer : %s does not exist in system." % (name))
|
||||
raise Exception
|
||||
|
||||
|
||||
# ====================================================================================================================
|
||||
def get_contact_details(self, arg):
|
||||
arg = eval(arg)
|
||||
contact = sql("select contact_no, email_id from `tabContact` where contact_name = '%s' and customer_name = '%s'" %(arg['contact_person'],arg['customer']), as_dict = 1)
|
||||
ret = {
|
||||
'contact_no' : contact and contact[0]['contact_no'] or '',
|
||||
'email_id' : contact and contact[0]['email_id'] or ''
|
||||
}
|
||||
return ret
|
||||
|
||||
# ====================================================================================================================
|
||||
def on_update(self):
|
||||
# Add to calendar
|
||||
#if self.doc.contact_date and self.doc.last_contact_date != self.doc.contact_date:
|
||||
if self.doc.contact_date and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if self.doc.contact_by:
|
||||
self.add_calendar_event()
|
||||
set(self.doc, 'contact_date_ref',self.doc.contact_date)
|
||||
set(self.doc, 'status', 'Draft')
|
||||
|
||||
# Add to Calendar
|
||||
# ====================================================================================================================
|
||||
def add_calendar_event(self):
|
||||
desc=''
|
||||
user_lst =[]
|
||||
if self.doc.customer:
|
||||
if self.doc.contact_person:
|
||||
desc = 'Contact '+cstr(self.doc.contact_person)
|
||||
else:
|
||||
desc = 'Contact customer '+cstr(self.doc.customer)
|
||||
elif self.doc.lead:
|
||||
if self.doc.lead_name:
|
||||
desc = 'Contact '+cstr(self.doc.lead_name)
|
||||
else:
|
||||
desc = 'Contact lead '+cstr(self.doc.lead)
|
||||
desc = desc+ '. By : ' + cstr(self.doc.contact_by)
|
||||
|
||||
if self.doc.to_discuss:
|
||||
desc = desc+' To Discuss : ' + cstr(self.doc.to_discuss)
|
||||
|
||||
ev = Document('Event')
|
||||
ev.description = desc
|
||||
ev.event_date = self.doc.contact_date
|
||||
ev.event_hour = '10:00'
|
||||
ev.event_type = 'Private'
|
||||
ev.ref_type = 'Opportunity'
|
||||
ev.ref_name = self.doc.name
|
||||
ev.save(1)
|
||||
|
||||
user_lst.append(self.doc.owner)
|
||||
|
||||
chk = sql("select t1.name from `tabProfile` t1, `tabSales Person` t2 where t2.email_id = t1.name and t2.name=%s",self.doc.contact_by)
|
||||
if chk:
|
||||
user_lst.append(chk[0][0])
|
||||
|
||||
for d in user_lst:
|
||||
ch = addchild(ev, 'event_individuals', 'Event User', 0)
|
||||
ch.person = d
|
||||
ch.save(1)
|
||||
|
||||
#--------------Validation For Last Contact Date-----------------
|
||||
# ====================================================================================================================
|
||||
def set_last_contact_date(self):
|
||||
if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if getdate(self.doc.contact_date_ref) < getdate(self.doc.contact_date):
|
||||
self.doc.last_contact_date=self.doc.contact_date_ref
|
||||
else:
|
||||
msgprint("Contact Date Cannot be before Last Contact Date")
|
||||
raise Exception
|
||||
|
||||
# check if item present in item table
|
||||
# ====================================================================================================================
|
||||
def validate_item_details(self):
|
||||
if not getlist(self.doclist, 'enquiry_details'):
|
||||
msgprint("Please select items for which enquiry needs to be made")
|
||||
raise Exception
|
||||
|
||||
#check if enquiry date in the range of fiscal year selected
|
||||
#=====================================================
|
||||
def validate_fiscal_year(self):
|
||||
fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%self.doc.fiscal_year)
|
||||
ysd=fy and fy[0][0] or ""
|
||||
yed=add_days(str(ysd),365)
|
||||
if str(self.doc.transaction_date) < str(ysd) or str(self.doc.transaction_date) > str(yed):
|
||||
msgprint("Opportunity Date is not within the Fiscal Year selected")
|
||||
raise Exception
|
||||
|
||||
def validate_lead_cust(self):
|
||||
if self.doc.enquiry_from == 'Lead' and not self.doc.lead:
|
||||
msgprint("Lead Id is mandatory if 'Opportunity From' is selected as Lead", raise_exception=1)
|
||||
elif self.doc.enquiry_from == 'Customer' and not self.doc.customer:
|
||||
msgprint("Customer is mandatory if 'Opportunity From' is selected as Customer", raise_exception=1)
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.set_last_contact_date()
|
||||
self.validate_item_details()
|
||||
self.validate_lead_cust()
|
||||
|
||||
# On Submit Functions
|
||||
# ====================================================================================================================
|
||||
def on_submit(self):
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
# ====================================================================================================================
|
||||
def on_cancel(self):
|
||||
chk = sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
||||
if chk:
|
||||
msgprint("Quotation No. "+cstr(chk[0][0])+" is submitted against this Opportunity. Thus can not be cancelled.")
|
||||
raise Exception
|
||||
else:
|
||||
set(self.doc, 'status', 'Cancelled')
|
||||
|
||||
# declare as enquiry lost
|
||||
#---------------------------
|
||||
def declare_enquiry_lost(self,arg):
|
||||
chk = sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
||||
if chk:
|
||||
msgprint("Quotation No. "+cstr(chk[0][0])+" is submitted against this Opportunity. Thus 'Opportunity Lost' can not be declared against it.")
|
||||
raise Exception
|
||||
else:
|
||||
set(self.doc, 'status', 'Opportunity Lost')
|
||||
set(self.doc, 'order_lost_reason', arg)
|
||||
return 'true'
|
||||
|
||||
#---------------------- Add details in follow up table----------------
|
||||
# ====================================================================================================================
|
||||
def add_in_follow_up(self,message,type):
|
||||
import datetime
|
||||
child = addchild( self.doc, 'follow_up', 'Communication Log', 1, self.doclist)
|
||||
child.date = datetime.datetime.now().date().strftime('%Y-%m-%d')
|
||||
child.notes = message
|
||||
child.follow_up_type = type
|
||||
child.save()
|
||||
|
||||
#-------------------SMS----------------------------------------------
|
||||
# ====================================================================================================================
|
||||
def send_sms(self):
|
||||
if not self.doc.sms_message:
|
||||
msgprint("Please enter message in SMS Section ")
|
||||
raise Exception
|
||||
elif not getlist(self.doclist, 'enquiry_sms_detail'):
|
||||
msgprint("Please mention mobile no. to which sms needs to be sent")
|
||||
raise Exception
|
||||
else:
|
||||
receiver_list = []
|
||||
for d in getlist(self.doclist,'enquiry_sms_detail'):
|
||||
if d.other_mobile_no:
|
||||
receiver_list.append(d.other_mobile_no)
|
||||
|
||||
if receiver_list:
|
||||
msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, self.doc.sms_message))
|
||||
self.add_in_follow_up(self.doc.sms_message,'SMS')
|
||||
640
selling/doctype/opportunity/opportunity.txt
Normal file
640
selling/doctype/opportunity/opportunity.txt
Normal file
@@ -0,0 +1,640 @@
|
||||
# DocType, Opportunity
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-15 12:14:52',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-31 12:42:38',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1324284087',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Transaction',
|
||||
'is_submittable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'search_fields': u'status,transaction_date,customer,lead,enquiry_type,territory,company',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'To %(customer_name)s%(lead_name)s on %(transaction_date)s',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Opportunity
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Opportunity'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Enter customer enquiry for which you might raise a quotation in future',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Basic Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'To manage multiple series please go to Setup > Manage Series',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Naming Series',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'naming_series',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'ENQUIRY\nENQ',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'enquiry_from',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Opportunity From',
|
||||
'oldfieldname': u'enquiry_from',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nLead\nCustomer',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer',
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'lead',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Lead',
|
||||
'oldfieldname': u'lead',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Lead',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'Draft',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'status',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Status',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nDraft\nSubmitted\nQuotation Sent\nOrder Confirmed\nOpportunity Lost\nCancelled',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'enquiry_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Opportunity Type',
|
||||
'oldfieldname': u'enquiry_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nSales\nMaintenance',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'items',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Items',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u"Items which do not exist in Item master can also be entered on customer's request",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'enquiry_details',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Opportunity Items',
|
||||
'oldfieldname': u'enquiry_details',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Opportunity Item',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Keep a track of communication related to this enquiry which will help for future reference.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'communication_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Communication History',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 1,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'communication_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Communication HTML',
|
||||
'oldfieldname': u'follow_up',
|
||||
'oldfieldtype': u'Table',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Contact Info',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_person',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Contact Person',
|
||||
'options': u'Contact',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Address',
|
||||
'options': u'Address',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Customer Name',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'address_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 0,
|
||||
'label': u'Address',
|
||||
'oldfieldname': u'address',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Contact',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_email',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Contact Email',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_mobile',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Contact Mobile No',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'lead_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'label': u'Name',
|
||||
'oldfieldname': u'lead_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:doc.enquiry_from=="Customer"',
|
||||
'description': u'<a href="javascript:cur_frm.cscript.CGHelp();">To Manage Customer Groups, click here</a>',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Group',
|
||||
'oldfieldname': u'customer_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer Group',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="javascript:cur_frm.cscript.TerritoryHelp();">To Manage Territory, click here</a>',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Territory',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Filing in Additional Information about the Opportunity will help you analyze your data better.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'more_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'More Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'Today',
|
||||
'description': u'The date at which current entry is made in system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transaction_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Opportunity Date',
|
||||
'oldfieldname': u'transaction_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'source',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Source',
|
||||
'oldfieldname': u'source',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u"\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign\nWalk In",
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Enter name of campaign if source of enquiry is campaign',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'campaign',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Campaign',
|
||||
'oldfieldname': u'campaign',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Campaign',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'order_lost_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Quotation Lost Reason',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'order_lost_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'report_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person who will contact the customer in future',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_by',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Next Contact By',
|
||||
'oldfieldname': u'contact_by',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Profile',
|
||||
'permlevel': 0,
|
||||
'width': u'75px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person will get a reminder on this date to contact the customer',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Next Contact Date',
|
||||
'oldfieldname': u'contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
'description': u'Date on which the lead was last contacted',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'last_contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Last Contact Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'last_contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'to_discuss',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'To Discuss',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'to_discuss',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amended_from',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Amended From',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amended_from',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amendment_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Amendment Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amendment_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
}
|
||||
]
|
||||
41
selling/doctype/opportunity/opportunity_list.js
Normal file
41
selling/doctype/opportunity/opportunity_list.js
Normal file
@@ -0,0 +1,41 @@
|
||||
wn.doclistviews['Opportunity'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
'tabOpportunity.enquiry_from',
|
||||
'tabOpportunity.lead_name',
|
||||
'tabOpportunity.customer_name',
|
||||
'tabOpportunity.status',
|
||||
'tabOpportunity.transaction_date',
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'source', 'enquiry_from', 'company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(['Order Confirmed', 'Quotation Sent']
|
||||
.indexOf(data.status)!=-1) {
|
||||
data.label_type = 'success';
|
||||
} else if(data.status == 'Draft') {
|
||||
data.label_type = 'info';
|
||||
} else if(data.status == 'Submit') {
|
||||
data.label_type = 'important';
|
||||
}
|
||||
data.status_html = repl('<span class="label label-%(label_type)s">%(status)s</span>', data);
|
||||
if(data.enquiry_from == 'Lead') {
|
||||
data.enquiry_name = repl('[%(enquiry_from)s] %(lead_name)s', data);
|
||||
} else {
|
||||
data.enquiry_name = repl('[%(enquiry_from)s] %(customer_name)s', data);
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '18%', content:'status_html'},
|
||||
{width: '52%', content:'enquiry_name+tags', css: {color:'#222'}},
|
||||
{width: '12%', content:'transaction_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Opportunity Date", type: "date"}
|
||||
]
|
||||
})
|
||||
1
selling/doctype/opportunity_item/__init__.py
Normal file
1
selling/doctype/opportunity_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
140
selling/doctype/opportunity_item/opportunity_item.txt
Normal file
140
selling/doctype/opportunity_item/opportunity_item.txt
Normal file
@@ -0,0 +1,140 @@
|
||||
# DocType, Opportunity Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:08',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:08',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 59
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Opportunity Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Opportunity Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'reqd': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Item Name',
|
||||
'oldfieldname': u'item_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'reqd': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Item Group',
|
||||
'oldfieldname': u'item_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item Group',
|
||||
'print_hide': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Brand',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'print_hide': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Basic Rate',
|
||||
'oldfieldname': u'basic_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'uom',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'UOM',
|
||||
'search_index': 0
|
||||
}
|
||||
]
|
||||
1
selling/doctype/plot_control/__init__.py
Normal file
1
selling/doctype/plot_control/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
246
selling/doctype/plot_control/plot_control.py
Normal file
246
selling/doctype/plot_control/plot_control.py
Normal file
@@ -0,0 +1,246 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self,doc,doclist = []):
|
||||
self.doc ,self.doclist = doc, doclist
|
||||
|
||||
#============================get monthly sales====================================================
|
||||
def get_monthwise_amount(self,lst):
|
||||
lst = lst.split(',')
|
||||
if not lst[1]:
|
||||
ret = convert_to_lists(sql("SELECT SUM(grand_total) AMOUNT,CASE MONTH(due_date) WHEN 1 THEN 'JAN' WHEN 2 THEN 'FEB' WHEN 3 THEN 'MAR' WHEN 4 THEN 'APR' WHEN 5 THEN 'MAY' WHEN 6 THEN 'JUN' WHEN 7 THEN 'JUL' WHEN 8 THEN 'AUG' WHEN 9 THEN 'SEP' WHEN 10 THEN 'OCT' WHEN 11 THEN 'NOV' WHEN 12 THEN 'DEC' END MONTHNAME FROM `tabSales Invoice` WHERE docstatus = 1 AND fiscal_year = '%s' GROUP BY MONTH(due_date) ORDER BY MONTH(due_date)"%lst[0]))
|
||||
else:
|
||||
ret = convert_to_lists(sql("select sum(t2.amount) AMOUNT ,CASE MONTH(t1.due_date) WHEN 1 THEN 'JAN' WHEN 2 THEN 'FEB' WHEN 3 THEN 'MAR' WHEN 4 THEN 'APR' WHEN 5 THEN 'MAY' WHEN 6 THEN 'JUN' WHEN 7 THEN 'JUL' WHEN 8 THEN 'AUG' WHEN 9 THEN 'SEP' WHEN 10 THEN 'OCT' WHEN 11 THEN 'NOV' WHEN 12 THEN 'DEC' END MONTHNAME from `tabSales Invoice` t1,`tabSales Invoice Item` t2 WHERE t1.name = t2.parent and t1.docstatus = 1 and t2.item_group = '%s' AND t1.fiscal_year = '%s' GROUP BY MONTH(t1.due_date) ORDER BY MONTH(t1.due_date)"%(lst[1],lst[0])))
|
||||
|
||||
m =cint(sql("select month('%s')"%(get_defaults()['year_start_date']))[0][0])
|
||||
|
||||
lst1 = [[1,'JAN'],[2 ,'FEB'], [3,'MAR'],[4,'APR'],[5,'MAY'],[6,'JUN'],[7,'JUL'],[8,'AUG'],[9,'SEP'],[10,'OCT'],[11,'NOV'],[12,'DEC']]
|
||||
lst2=[]
|
||||
k=1
|
||||
|
||||
for i in range(1,13):
|
||||
for j in lst1:
|
||||
if j[0]==m:
|
||||
lst2.append([k,j[1]])
|
||||
m +=1
|
||||
if m==13: m=1
|
||||
k +=1
|
||||
return {'msg_data':ret,'x_axis':lst2}
|
||||
|
||||
#===============================get weekly sales=================================================
|
||||
def get_weekwise_amount(self,lst):
|
||||
|
||||
lst = lst.split(',')
|
||||
|
||||
cases = self.get_week_cases(lst[0],lst[1])
|
||||
|
||||
if not lst[2]:
|
||||
query = "SELECT SUM(grand_total) AMOUNT,CASE WEEK(due_date)"+ cases +"END Weekly FROM `tabSales Invoice` WHERE MONTH(due_date) = %d AND docstatus = 1 AND fiscal_year = '%s' GROUP BY Weekly ORDER BY Weekly"
|
||||
|
||||
ret = convert_to_lists(sql(query%(cint(lst[0]),lst[1])))
|
||||
|
||||
else:
|
||||
|
||||
query = "SELECT SUM(t2.amount) AMOUNT,CASE WEEK(t1.due_date)" + cases + "END Weekly FROM `tabSales Invoice` t1, `tabSales Invoice Item` t2 WHERE MONTH(t1.due_date) = %d AND t1.docstatus = 1 AND t1.fiscal_year = '%s' AND t1.name = t2.parent AND t2.item_group ='%s' GROUP BY Weekly ORDER BY Weekly"
|
||||
|
||||
ret =convert_to_lists(sql(query%(cint(lst[0]),lst[1],lst[2])))
|
||||
|
||||
return ret and ret or ''
|
||||
#================================================================================
|
||||
def get_week_cases(self,m1,fy):
|
||||
d1 = self.make_date("%s,%s"%(cstr(m1),fy))
|
||||
|
||||
w = sql("select week('%s'),week(last_day('%s'))"%(d1,d1))
|
||||
w1 = cint(w[0][0])
|
||||
w2 = cint(w[0][1])
|
||||
|
||||
w3 = []
|
||||
str1 = " "
|
||||
for i in range(1,7):
|
||||
if(w1 <= w2):
|
||||
w3.append(w1)
|
||||
str1 += "WHEN "+ cstr(w1) +" THEN 'Week"+cstr(i) +"' "
|
||||
w1 += 1
|
||||
|
||||
return str1
|
||||
|
||||
#===============================get yearly weekwise sales=================================================
|
||||
def get_year_weekwise_amount(self,lst):
|
||||
|
||||
lst = lst.split(',')
|
||||
yr_st = get_defaults()['year_start_date']
|
||||
|
||||
fy = lst[0]
|
||||
m1 = cint(yr_st.split('-')[1])
|
||||
|
||||
cases = ' '
|
||||
for i in range(1,13):
|
||||
cases += self.get_week_cases(m1,fy)
|
||||
m1 +=1
|
||||
if(m1 == 13): m1 = 1
|
||||
|
||||
if not lst[1]:
|
||||
query = "SELECT SUM(grand_total) AMOUNT,CASE WEEK(due_date)"+cases+"END Weekly, month(due_date) month FROM `tabSales Invoice` WHERE docstatus = 1 AND fiscal_year = '%s' GROUP BY `month`,weekly ORDER BY `month`,weekly"
|
||||
ret = convert_to_lists(sql(query%lst[0]))
|
||||
|
||||
else:
|
||||
|
||||
query = "SELECT SUM(t2.amount) AMOUNT,CASE WEEK(t1.due_date)" + cases + "END Weekly, month(due_date) month FROM `tabSales Invoice` t1, `tabSales Invoice Item` t2 WHERE t1.docstatus = 1 AND t1.fiscal_year = '%s' AND t1.name = t2.parent AND t2.item_group ='%s' GROUP BY Weekly ORDER BY Weekly"
|
||||
ret = convert_to_lists(sql(query%(lst[0],lst[1])))
|
||||
|
||||
|
||||
return ret and ret or ''
|
||||
|
||||
|
||||
#====================================make yearly weekwise dates================================================
|
||||
def yr_wk_dates(self,fy):
|
||||
|
||||
from datetime import date
|
||||
yr_st = get_defaults()['year_start_date']
|
||||
yr_en = get_defaults()['year_end_date']
|
||||
|
||||
fy = fy.split('-')
|
||||
y1 = yr_st.split('-')
|
||||
date1 = date(cint(fy[0]),cint(y1[1]),cint(y1[2]))
|
||||
|
||||
y2 = yr_en.split('-')
|
||||
date2 = date(cint(fy[1]),cint(y2[1]),cint(y2[2]))
|
||||
|
||||
|
||||
|
||||
date_lst = [[1,self.get_months(cint(y1[1]))]]
|
||||
m1=cint(y1[1])+1
|
||||
x_axis_lst = [[1,'Week1',cint(y1[1])]]
|
||||
|
||||
from datetime import date, timedelta
|
||||
d =dt= date1
|
||||
|
||||
week=k=1
|
||||
for i in range(0,53):
|
||||
|
||||
if dt <= date2:
|
||||
|
||||
if(d.weekday()>3):
|
||||
d = d+timedelta(7-d.weekday())
|
||||
else:
|
||||
d = d - timedelta(d.weekday())
|
||||
dlt = timedelta(days = (week-1)*7)
|
||||
dt = d + dlt + timedelta(days=6)
|
||||
|
||||
m2 = cint(sql("Select month('%s')"%dt)[0][0])
|
||||
|
||||
if(m1 == m2):
|
||||
date_lst.append([i+2,self.get_months(m2)])
|
||||
x_axis_lst.append([i+2,'Week1',m2])
|
||||
k=1
|
||||
m1 += 1
|
||||
if(m1==13): m1 =1
|
||||
else:
|
||||
date_lst.append([i+2,' '])
|
||||
x_axis_lst.append([i+2,'Week%d'%k,m2])
|
||||
week += 1
|
||||
k +=1
|
||||
|
||||
|
||||
return [date_lst,x_axis_lst]
|
||||
#===================================================================================
|
||||
|
||||
def get_months(self,m):
|
||||
m_lst = {1:'JAN',2:'FEB',3:'MAR',4:'APR',5:'MAY',6:'JUN',7:'JUL',8:'AUG',9:'SEP',10:'OCT',11:'NOV',12:'DEC'}
|
||||
return m_lst[m]
|
||||
|
||||
|
||||
|
||||
def get_weekdates(self,lst):
|
||||
from datetime import date, timedelta
|
||||
|
||||
d = dt = self.make_date(lst)
|
||||
date_lst = [[1,cstr(d.strftime("%d/%m/%y"))]]
|
||||
week=flag =1
|
||||
j=1
|
||||
last_day = sql("select last_day('%s')"%d)[0][0]
|
||||
lst_m = cint(lst.split(',')[0])
|
||||
for i in range(2,8):
|
||||
f=0
|
||||
if(dt < last_day):
|
||||
#if(d.weekday()>4):
|
||||
#d = d+timedelta(7-d.weekday())
|
||||
#else:
|
||||
d = d - timedelta(d.weekday()-1)
|
||||
dlt = timedelta(days = (week-1)*7)
|
||||
dt = d + dlt + timedelta(days=6)
|
||||
|
||||
if(cint(sql("select month('%s')"%dt)[0][0]) == lst_m and dt!=last_day):
|
||||
for k in date_lst:
|
||||
if(cstr(dt.strftime("%d/%m/%y")) == k[1]):
|
||||
f = 1
|
||||
if f == 0:
|
||||
date_lst.append([i,cstr(dt.strftime("%d/%m/%y"))])
|
||||
|
||||
elif(dt==last_day and flag ==1):
|
||||
date_lst.append([i,cstr(last_day.strftime("%d/%m/%y"))])
|
||||
flag = 0
|
||||
|
||||
elif(flag == 1):
|
||||
date_lst.append([i,cstr(last_day.strftime("%d/%m/%y"))])
|
||||
week += 1
|
||||
|
||||
return date_lst and date_lst or ''
|
||||
|
||||
|
||||
def make_date(self,lst):
|
||||
|
||||
from datetime import date, timedelta
|
||||
lst = lst.split(',')
|
||||
year = lst[1].split('-')
|
||||
if(len(lst[0])==1): month = '0'+lst[0]
|
||||
else: month = lst[0]
|
||||
if(1<=cint(month)<=3): year = year[1]
|
||||
elif(4<=cint(month)<=12): year = year[0]
|
||||
|
||||
d = date(cint(year),cint(month),1)
|
||||
|
||||
return d
|
||||
|
||||
def get_item_groups(self):
|
||||
ret = convert_to_lists(sql("select name from `tabItem Group` where docstatus != 2 and is_group = 'No'"))
|
||||
#ret = convert_to_lists(sql("select item_group from `tabItem` where is_sales_item='Yes' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) and item_group !=''"))
|
||||
return ret and ret or ''
|
||||
|
||||
def get_fiscal_year(self):
|
||||
ret = convert_to_lists(sql("select name from `tabFiscal Year` where docstatus =0"))
|
||||
return ret and ret or ''
|
||||
30
selling/doctype/plot_control/plot_control.txt
Normal file
30
selling/doctype/plot_control/plot_control.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
# DocType, Plot Control
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:12',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:12',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'harshada@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'issingle': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 215
|
||||
},
|
||||
|
||||
# DocType, Plot Control
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Plot Control'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/quotation/__init__.py
Normal file
1
selling/doctype/quotation/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
340
selling/doctype/quotation/quotation.js
Normal file
340
selling/doctype/quotation/quotation.js
Normal file
@@ -0,0 +1,340 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Module CRM
|
||||
cur_frm.cscript.tname = "Quotation Item";
|
||||
cur_frm.cscript.fname = "quotation_details";
|
||||
cur_frm.cscript.other_fname = "other_charges";
|
||||
cur_frm.cscript.sales_team_fname = "sales_team";
|
||||
|
||||
// =====================================================================================
|
||||
wn.require('erpnext/selling/doctype/sales_common/sales_common.js');
|
||||
wn.require('erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/setup/doctype/notification_control/notification_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
// ONLOAD
|
||||
// ===================================================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(!doc.quotation_to) hide_field(['customer','customer_address','contact_person','customer_name','lead', 'lead_name', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']);
|
||||
if(!doc.price_list_name) set_multiple(cdt,cdn,{price_list_name:sys_defaults.price_list_name});
|
||||
if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'});
|
||||
if(!doc.transaction_date) set_multiple(cdt,cdn,{transaction_date:get_today()});
|
||||
if(!doc.conversion_rate) set_multiple(cdt,cdn,{conversion_rate:'1.00'});
|
||||
if(!doc.currency && sys_defaults.currency) set_multiple(cdt,cdn,{currency:sys_defaults.currency});
|
||||
if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
|
||||
|
||||
if(!doc.company && sys_defaults.company) set_multiple(cdt,cdn,{company:sys_defaults.company});
|
||||
if(!doc.fiscal_year && sys_defaults.fiscal_year) set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year});
|
||||
|
||||
if(doc.quotation_to) {
|
||||
if(doc.quotation_to == 'Customer') {
|
||||
hide_field(['lead', 'lead_name', 'organization']);
|
||||
}
|
||||
else if (doc.quotation_to == 'Lead') {
|
||||
hide_field(['customer','customer_address','contact_person', 'customer_name','contact_display', 'customer_group']);
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
|
||||
var callback = function(doc, dt, dn) {
|
||||
// defined in sales_common.js
|
||||
cur_frm.cscript.update_item_details(doc, dt, dn);
|
||||
}
|
||||
cur_frm.cscript.hide_price_list_currency(doc, dt, dn, callback);
|
||||
}
|
||||
|
||||
// hide - unhide fields based on lead or customer..
|
||||
// =======================================================================================================================
|
||||
cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){
|
||||
hide_field(['lead', 'lead_name','customer','customer_address','contact_person',
|
||||
'customer_name','address_display','contact_display','contact_mobile','contact_email',
|
||||
'territory','customer_group', 'organization']);
|
||||
if(doc.quotation_to == 'Lead') unhide_field(['lead']);
|
||||
else if(doc.quotation_to == 'Customer') unhide_field(['customer']);
|
||||
|
||||
doc.lead = doc.lead_name = doc.customer = doc.customer_name = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = doc.organization = "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================ hide - unhide fields on basis of quotation to either lead or customer ===============================
|
||||
cur_frm.cscript.quotation_to = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.lead_cust_show(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
|
||||
// REFRESH
|
||||
// ===================================================================================
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
|
||||
cur_frm.clear_custom_buttons();
|
||||
|
||||
if (!cur_frm.cscript.is_onload) cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn);
|
||||
|
||||
|
||||
if(doc.docstatus == 1 && doc.status!='Order Lost') {
|
||||
cur_frm.add_custom_button('Make Sales Order', cur_frm.cscript['Make Sales Order']);
|
||||
cur_frm.add_custom_button('Set as Lost', cur_frm.cscript['Declare Order Lost']);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
}
|
||||
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
if(doc.customer || doc.lead) $(cur_frm.fields_dict.contact_section.row.wrapper).toggle(true);
|
||||
else $(cur_frm.fields_dict.contact_section.row.wrapper).toggle(false);
|
||||
|
||||
if (!doc.__islocal) cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
var pl = doc.price_list_name;
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
cur_frm.refresh();
|
||||
if (pl != doc.price_list_name) cur_frm.cscript.price_list_name(doc, dt, dn);
|
||||
}
|
||||
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name),
|
||||
'get_default_customer_address', '', callback);
|
||||
if(doc.customer) unhide_field(['customer_address','contact_person','territory', 'customer_group']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({
|
||||
customer: doc.customer,
|
||||
address: doc.customer_address,
|
||||
contact: doc.contact_person
|
||||
}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
//lead
|
||||
cur_frm.fields_dict['lead'].get_query = function(doc,cdt,cdn){
|
||||
return 'SELECT `tabLead`.name, `tabLead`.lead_name FROM `tabLead` WHERE `tabLead`.%(key)s LIKE "%s" ORDER BY `tabLead`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
||||
if(doc.lead) {
|
||||
get_server_fields('get_lead_details', doc.lead,'', doc, cdt, cdn, 1);
|
||||
unhide_field('territory');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
cur_frm.fields_dict['enq_no'].get_query = function(doc,cdt,cdn){
|
||||
var cond='';
|
||||
var cond1='';
|
||||
if(doc.order_type) cond = 'ifnull(`tabOpportunity`.enquiry_type, "") = "'+doc.order_type+'" AND';
|
||||
if(doc.customer) cond1 = '`tabOpportunity`.customer = "'+doc.customer+'" AND';
|
||||
else if(doc.lead) cond1 = '`tabOpportunity`.lead = "'+doc.lead+'" AND';
|
||||
|
||||
return repl('SELECT `tabOpportunity`.`name` FROM `tabOpportunity` WHERE `tabOpportunity`.`docstatus` = 1 AND `tabOpportunity`.status = "Submitted" AND %(cond)s %(cond1)s `tabOpportunity`.`name` LIKE "%s" ORDER BY `tabOpportunity`.`name` ASC LIMIT 50', {cond:cond, cond1:cond1});
|
||||
}
|
||||
|
||||
// Make Sales Order
|
||||
// =====================================================================================
|
||||
cur_frm.cscript['Make Sales Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
if (doc.docstatus == 1) {
|
||||
var n = createLocal("Sales Order");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Sales Order"][n]]),
|
||||
'from_doctype':'Quotation',
|
||||
'to_doctype':'Sales Order',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Quotation', 'Sales Order'], ['Quotation Item', 'Sales Order Item'],['Sales Taxes and Charges','Sales Taxes and Charges'], ['Sales Team', 'Sales Team'], ['TC Detail', 'TC Detail']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc("Sales Order", n);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//pull enquiry details
|
||||
cur_frm.cscript.pull_enquiry_detail = function(doc,cdt,cdn){
|
||||
|
||||
var callback = function(r,rt){
|
||||
if(r.message){
|
||||
doc.quotation_to = r.message;
|
||||
|
||||
if(doc.quotation_to == 'Lead') {
|
||||
unhide_field('lead');
|
||||
}
|
||||
else if(doc.quotation_to == 'Customer') {
|
||||
unhide_field(['customer','customer_address','contact_person','territory','customer_group']);
|
||||
}
|
||||
refresh_many(['quotation_details','quotation_to','customer','customer_address','contact_person','lead','lead_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group','order_type']);
|
||||
}
|
||||
}
|
||||
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_enq_details','',callback);
|
||||
|
||||
}
|
||||
|
||||
// declare order lost
|
||||
//-------------------------
|
||||
cur_frm.cscript['Declare Order Lost'] = function(){
|
||||
var qtn_lost_dialog;
|
||||
|
||||
set_qtn_lost_dialog = function(doc,cdt,cdn){
|
||||
qtn_lost_dialog = new Dialog(400,400,'Add Quotation Lost Reason');
|
||||
qtn_lost_dialog.make_body([
|
||||
['HTML', 'Message', '<div class="comment">Please add quotation lost reason</div>'],
|
||||
['Text', 'Quotation Lost Reason'],
|
||||
['HTML', 'Response', '<div class = "comment" id="update_quotation_dialog_response"></div>'],
|
||||
['HTML', 'Add Reason', '<div></div>']
|
||||
]);
|
||||
|
||||
var add_reason_btn1 = $a($i(qtn_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn1.innerHTML = 'Add';
|
||||
add_reason_btn1.onclick = function(){ qtn_lost_dialog.add(); }
|
||||
|
||||
var add_reason_btn2 = $a($i(qtn_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn2.innerHTML = 'Cancel';
|
||||
$y(add_reason_btn2,{marginLeft:'4px'});
|
||||
add_reason_btn2.onclick = function(){ qtn_lost_dialog.hide();}
|
||||
|
||||
qtn_lost_dialog.onshow = function() {
|
||||
qtn_lost_dialog.widgets['Quotation Lost Reason'].value = '';
|
||||
$i('update_quotation_dialog_response').innerHTML = '';
|
||||
}
|
||||
|
||||
qtn_lost_dialog.add = function() {
|
||||
// sending...
|
||||
$i('update_quotation_dialog_response').innerHTML = 'Processing...';
|
||||
var arg = strip(qtn_lost_dialog.widgets['Quotation Lost Reason'].value);
|
||||
var call_back = function(r,rt) {
|
||||
if(r.message == 'true'){
|
||||
$i('update_quotation_dialog_response').innerHTML = 'Done';
|
||||
qtn_lost_dialog.hide();
|
||||
}
|
||||
}
|
||||
if(arg) $c_obj(make_doclist(cur_frm.doc.doctype, cur_frm.doc.name),'declare_order_lost',arg,call_back);
|
||||
else msgprint("Please add Quotation lost reason");
|
||||
}
|
||||
}
|
||||
|
||||
if(!qtn_lost_dialog){
|
||||
set_qtn_lost_dialog(doc,cdt,cdn);
|
||||
}
|
||||
qtn_lost_dialog.show();
|
||||
}
|
||||
|
||||
//===================== Quotation to validation - either customer or lead mandatory ====================
|
||||
cur_frm.cscript.quot_to_validate = function(doc,cdt,cdn){
|
||||
|
||||
if(doc.quotation_to == 'Lead'){
|
||||
|
||||
if(!doc.lead){
|
||||
alert("Lead is mandatory.");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
else if(doc.quotation_to == 'Customer'){
|
||||
if(!doc.customer){
|
||||
alert("Customer is mandatory.");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===================validation function =================================
|
||||
|
||||
cur_frm.cscript.validate = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.recalculate_values(doc, cdt, cdn);
|
||||
cur_frm.cscript.quot_to_validate(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
//================ Last Quoted Price and Last Sold Price suggestion ======================
|
||||
cur_frm.fields_dict['quotation_details'].grid.get_field('item_code').get_query= function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
var cond = (doc.order_type == 'Maintenance') ? " and item.is_service_item = 'Yes'" : " and item.is_sales_item = 'Yes'";
|
||||
if(doc.customer) {
|
||||
var export_rate_field = wn.meta.get_docfield(cdt, 'export_rate', cdn);
|
||||
var precision = (export_rate_field && export_rate_field.fieldtype) === 'Float' ? 6 : 2;
|
||||
return repl("\
|
||||
select \
|
||||
item.name, \
|
||||
( \
|
||||
select concat('Last Quote @ ', q.currency, ' ', \
|
||||
format(q_item.export_rate, %(precision)s)) \
|
||||
from `tabQuotation` q, `tabQuotation Item` q_item \
|
||||
where \
|
||||
q.name = q_item.parent \
|
||||
and q_item.item_code = item.name \
|
||||
and q.docstatus = 1 \
|
||||
and q.customer = \"%(cust)s\" \
|
||||
order by q.transaction_date desc \
|
||||
limit 1 \
|
||||
) as quote_rate, \
|
||||
( \
|
||||
select concat('Last Sale @ ', si.currency, ' ', \
|
||||
format(si_item.basic_rate, %(precision)s)) \
|
||||
from `tabSales Invoice` si, `tabSales Invoice Item` si_item \
|
||||
where \
|
||||
si.name = si_item.parent \
|
||||
and si_item.item_code = item.name \
|
||||
and si.docstatus = 1 \
|
||||
and si.customer = \"%(cust)s\" \
|
||||
order by si.voucher_date desc \
|
||||
limit 1 \
|
||||
) as sales_rate, \
|
||||
item.item_name, item.description \
|
||||
from `tabItem` item \
|
||||
where \
|
||||
item.%(key)s like \"%s\" \
|
||||
%(cond)s \
|
||||
limit 25", {
|
||||
cust: doc.customer,
|
||||
cond: cond,
|
||||
precision: precision
|
||||
});
|
||||
} else {
|
||||
return repl("SELECT name, item_name, description FROM `tabItem` item WHERE item.%(key)s LIKE '%s' %(cond)s ORDER BY item.item_code DESC LIMIT 50", {cond:cond});
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
||||
var args = {
|
||||
type: 'Quotation',
|
||||
doctype: 'Quotation'
|
||||
}
|
||||
cur_frm.cscript.notify(doc, args);
|
||||
}
|
||||
355
selling/doctype/quotation/quotation.py
Normal file
355
selling/doctype/quotation/quotation.py
Normal file
@@ -0,0 +1,355 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, load_json
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.tname = 'Quotation Item'
|
||||
self.fname = 'quotation_details'
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# DOCTYPE TRIGGER FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# Pull Opportunity Details
|
||||
# --------------------
|
||||
def pull_enq_details(self):
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'quotation_details')
|
||||
get_obj('DocType Mapper', 'Opportunity-Quotation').dt_map('Opportunity', 'Quotation', self.doc.enq_no, self.doc, self.doclist, "[['Opportunity', 'Quotation'],['Opportunity Item', 'Quotation Item']]")
|
||||
|
||||
self.get_adj_percent()
|
||||
|
||||
return self.doc.quotation_to
|
||||
|
||||
# Get contact person details based on customer selected
|
||||
# ------------------------------------------------------
|
||||
def get_contact_details(self):
|
||||
return get_obj('Sales Common').get_contact_details(self,0)
|
||||
|
||||
|
||||
|
||||
# QUOTATION DETAILS TRIGGER FUNCTIONS
|
||||
# ================================================================================
|
||||
|
||||
# Get Item Details
|
||||
# -----------------
|
||||
def get_item_details(self, args=None):
|
||||
import json
|
||||
args = args and json.loads(args) or {}
|
||||
if args.get('item_code'):
|
||||
return get_obj('Sales Common').get_item_details(args, self)
|
||||
else:
|
||||
obj = get_obj('Sales Common')
|
||||
for doc in self.doclist:
|
||||
if doc.fields.get('item_code'):
|
||||
arg = {
|
||||
'item_code': doc.fields.get('item_code'),
|
||||
'income_account': doc.fields.get('income_account'),
|
||||
'cost_center': doc.fields.get('cost_center'),
|
||||
'warehouse': doc.fields.get('warehouse')
|
||||
}
|
||||
res = obj.get_item_details(arg, self) or {}
|
||||
for r in res:
|
||||
if not doc.fields.get(r):
|
||||
doc.fields[r] = res[r]
|
||||
|
||||
# Re-calculates Basic Rate & amount based on Price List Selected
|
||||
# --------------------------------------------------------------
|
||||
def get_adj_percent(self, arg=''):
|
||||
get_obj('Sales Common').get_adj_percent(self)
|
||||
|
||||
|
||||
|
||||
|
||||
# OTHER CHARGES TRIGGER FUNCTIONS
|
||||
# ====================================================================================
|
||||
|
||||
# Get Tax rate if account type is TAX
|
||||
# -----------------------------------
|
||||
def get_rate(self,arg):
|
||||
return get_obj('Sales Common').get_rate(arg)
|
||||
|
||||
# Load Default Charges
|
||||
# ----------------------------------------------------------
|
||||
def load_default_taxes(self):
|
||||
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
||||
|
||||
# Pull details from other charges master (Get Sales Taxes and Charges Master)
|
||||
# ----------------------------------------------------------
|
||||
def get_other_charges(self):
|
||||
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
||||
|
||||
|
||||
# GET TERMS AND CONDITIONS
|
||||
# ====================================================================================
|
||||
def get_tc_details(self):
|
||||
return get_obj('Sales Common').get_tc_details(self)
|
||||
|
||||
|
||||
# VALIDATE
|
||||
# ==============================================================================================
|
||||
|
||||
# Amendment date is necessary if document is amended
|
||||
# --------------------------------------------------
|
||||
def validate_mandatory(self):
|
||||
if self.doc.amended_from and not self.doc.amendment_date:
|
||||
msgprint("Please Enter Amendment Date")
|
||||
raise Exception
|
||||
|
||||
# Fiscal Year Validation
|
||||
# ----------------------
|
||||
def validate_fiscal_year(self):
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Quotation Date')
|
||||
|
||||
# Does not allow same item code to be entered twice
|
||||
# -------------------------------------------------
|
||||
def validate_for_items(self):
|
||||
chk_dupl_itm = []
|
||||
for d in getlist(self.doclist,'quotation_details'):
|
||||
if [cstr(d.item_code),cstr(d.description)] in chk_dupl_itm:
|
||||
msgprint("Item %s has been entered twice. Please change description atleast to continue" % d.item_code)
|
||||
raise Exception
|
||||
else:
|
||||
chk_dupl_itm.append([cstr(d.item_code),cstr(d.description)])
|
||||
|
||||
|
||||
#do not allow sales item in maintenance quotation and service item in sales quotation
|
||||
#-----------------------------------------------------------------------------------------------
|
||||
def validate_order_type(self):
|
||||
if self.doc.order_type in ['Maintenance', 'Service']:
|
||||
for d in getlist(self.doclist, 'quotation_details'):
|
||||
is_service_item = sql("select is_service_item from `tabItem` where name=%s", d.item_code)
|
||||
is_service_item = is_service_item and is_service_item[0][0] or 'No'
|
||||
|
||||
if is_service_item == 'No':
|
||||
msgprint("You can not select non service item "+d.item_code+" in Maintenance Quotation")
|
||||
raise Exception
|
||||
else:
|
||||
for d in getlist(self.doclist, 'quotation_details'):
|
||||
is_sales_item = sql("select is_sales_item from `tabItem` where name=%s", d.item_code)
|
||||
is_sales_item = is_sales_item and is_sales_item[0][0] or 'No'
|
||||
|
||||
if is_sales_item == 'No':
|
||||
msgprint("You can not select non sales item "+d.item_code+" in Sales Quotation")
|
||||
raise Exception
|
||||
|
||||
#--------------Validation For Last Contact Date-----------------
|
||||
# ====================================================================================================================
|
||||
def set_last_contact_date(self):
|
||||
#if not self.doc.contact_date_ref:
|
||||
#self.doc.contact_date_ref=self.doc.contact_date
|
||||
#self.doc.last_contact_date=self.doc.contact_date_ref
|
||||
if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if getdate(self.doc.contact_date_ref) < getdate(self.doc.contact_date):
|
||||
self.doc.last_contact_date=self.doc.contact_date_ref
|
||||
else:
|
||||
msgprint("Contact Date Cannot be before Last Contact Date")
|
||||
raise Exception
|
||||
#set(self.doc, 'contact_date_ref',self.doc.contact_date)
|
||||
|
||||
|
||||
# Validate
|
||||
# --------
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.validate_mandatory()
|
||||
self.set_last_contact_date()
|
||||
self.validate_order_type()
|
||||
self.validate_for_items()
|
||||
sales_com_obj = get_obj('Sales Common')
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.validate_max_discount(self,'quotation_details') #verify whether rate is not greater than max_discount
|
||||
sales_com_obj.check_conversion_rate(self)
|
||||
|
||||
# Get total in words
|
||||
dcc = TransactionBase().get_company_currency(self.doc.company)
|
||||
self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total)
|
||||
self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
|
||||
|
||||
def on_update(self):
|
||||
# Add to calendar
|
||||
if self.doc.contact_date and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if self.doc.contact_by:
|
||||
self.add_calendar_event()
|
||||
set(self.doc, 'contact_date_ref',self.doc.contact_date)
|
||||
|
||||
# Set Quotation Status
|
||||
set(self.doc, 'status', 'Draft')
|
||||
|
||||
# subject for follow
|
||||
self.doc.subject = '[%(status)s] To %(customer)s worth %(currency)s %(grand_total)s' % self.doc.fields
|
||||
|
||||
|
||||
# Add to Calendar
|
||||
# ====================================================================================================================
|
||||
def add_calendar_event(self):
|
||||
desc=''
|
||||
user_lst =[]
|
||||
if self.doc.customer:
|
||||
if self.doc.contact_person:
|
||||
desc = 'Contact '+cstr(self.doc.contact_person)
|
||||
else:
|
||||
desc = 'Contact customer '+cstr(self.doc.customer)
|
||||
elif self.doc.lead:
|
||||
if self.doc.lead_name:
|
||||
desc = 'Contact '+cstr(self.doc.lead_name)
|
||||
else:
|
||||
desc = 'Contact lead '+cstr(self.doc.lead)
|
||||
desc = desc+ '.By : ' + cstr(self.doc.contact_by)
|
||||
|
||||
if self.doc.to_discuss:
|
||||
desc = desc+' To Discuss : ' + cstr(self.doc.to_discuss)
|
||||
|
||||
ev = Document('Event')
|
||||
ev.description = desc
|
||||
ev.event_date = self.doc.contact_date
|
||||
ev.event_hour = '10:00'
|
||||
ev.event_type = 'Private'
|
||||
ev.ref_type = 'Opportunity'
|
||||
ev.ref_name = self.doc.name
|
||||
ev.save(1)
|
||||
|
||||
user_lst.append(self.doc.owner)
|
||||
|
||||
chk = sql("select t1.name from `tabProfile` t1, `tabSales Person` t2 where t2.email_id = t1.name and t2.name=%s",self.doc.contact_by)
|
||||
if chk:
|
||||
user_lst.append(chk[0][0])
|
||||
|
||||
for d in user_lst:
|
||||
ch = addchild(ev, 'event_individuals', 'Event User', 0)
|
||||
ch.person = d
|
||||
ch.save(1)
|
||||
|
||||
#update enquiry
|
||||
#------------------
|
||||
def update_enquiry(self, flag):
|
||||
prevdoc=''
|
||||
for d in getlist(self.doclist, 'quotation_details'):
|
||||
if d.prevdoc_docname:
|
||||
prevdoc = d.prevdoc_docname
|
||||
|
||||
if prevdoc:
|
||||
if flag == 'submit': #on submit
|
||||
sql("update `tabOpportunity` set status = 'Quotation Sent' where name = %s", prevdoc)
|
||||
elif flag == 'cancel': #on cancel
|
||||
sql("update `tabOpportunity` set status = 'Open' where name = %s", prevdoc)
|
||||
elif flag == 'order lost': #order lost
|
||||
sql("update `tabOpportunity` set status = 'Opportunity Lost' where name=%s", prevdoc)
|
||||
elif flag == 'order confirm': #order confirm
|
||||
sql("update `tabOpportunity` set status='Order Confirmed' where name=%s", prevdoc)
|
||||
|
||||
# declare as order lost
|
||||
#-------------------------
|
||||
def declare_order_lost(self,arg):
|
||||
chk = sql("select t1.name from `tabSales Order` t1, `tabSales Order Item` t2 where t2.parent = t1.name and t1.docstatus=1 and t2.prevdoc_docname = %s",self.doc.name)
|
||||
if chk:
|
||||
msgprint("Sales Order No. "+cstr(chk[0][0])+" is submitted against this Quotation. Thus 'Order Lost' can not be declared against it.")
|
||||
raise Exception
|
||||
else:
|
||||
set(self.doc, 'status', 'Order Lost')
|
||||
set(self.doc, 'order_lost_reason', arg)
|
||||
self.update_enquiry('order lost')
|
||||
return 'true'
|
||||
|
||||
#check if value entered in item table
|
||||
#--------------------------------------
|
||||
def check_item_table(self):
|
||||
if not getlist(self.doclist, 'quotation_details'):
|
||||
msgprint("Please enter item details")
|
||||
raise Exception
|
||||
|
||||
# ON SUBMIT
|
||||
# =========================================================================
|
||||
def on_submit(self):
|
||||
self.check_item_table()
|
||||
if not self.doc.amended_from:
|
||||
set(self.doc, 'message', 'Quotation: '+self.doc.name+' has been sent')
|
||||
else:
|
||||
set(self.doc, 'message', 'Quotation has been amended. New Quotation no:'+self.doc.name)
|
||||
|
||||
# Check for Approving Authority
|
||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
|
||||
|
||||
# Set Quotation Status
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
#update enquiry status
|
||||
self.update_enquiry('submit')
|
||||
|
||||
|
||||
# ON CANCEL
|
||||
# ==========================================================================
|
||||
def on_cancel(self):
|
||||
set(self.doc, 'message', 'Quotation: '+self.doc.name+' has been cancelled')
|
||||
|
||||
#update enquiry status
|
||||
self.update_enquiry('cancel')
|
||||
|
||||
set(self.doc,'status','Cancelled')
|
||||
|
||||
|
||||
# SEND SMS
|
||||
# =============================================================================
|
||||
def send_sms(self):
|
||||
if not self.doc.customer_mobile_no:
|
||||
msgprint("Please enter customer mobile no")
|
||||
elif not self.doc.message:
|
||||
msgprint("Please enter the message you want to send")
|
||||
else:
|
||||
msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.contact_mobile,], self.doc.message))
|
||||
|
||||
# Print other charges
|
||||
# ===========================================================================
|
||||
def print_other_charges(self,docname):
|
||||
print_lst = []
|
||||
for d in getlist(self.doclist,'other_charges'):
|
||||
lst1 = []
|
||||
lst1.append(d.description)
|
||||
lst1.append(d.total)
|
||||
print_lst.append(lst1)
|
||||
return print_lst
|
||||
|
||||
def update_followup_details(self):
|
||||
sql("delete from `tabCommunication Log` where parent = '%s'"%self.doc.name)
|
||||
for d in getlist(self.doclist, 'follow_up'):
|
||||
d.save()
|
||||
1275
selling/doctype/quotation/quotation.txt
Normal file
1275
selling/doctype/quotation/quotation.txt
Normal file
File diff suppressed because it is too large
Load Diff
44
selling/doctype/quotation/quotation_list.js
Normal file
44
selling/doctype/quotation/quotation_list.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// render
|
||||
wn.doclistviews['Quotation'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabQuotation`.quotation_to",
|
||||
"`tabQuotation`.lead_name",
|
||||
"`tabQuotation`.customer_name",
|
||||
"`tabQuotation`.currency",
|
||||
"ifnull(`tabQuotation`.grand_total_export,0) as grand_total_export",
|
||||
"`tabQuotation`.transaction_date",
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'quotation_to', 'company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(data.quotation_to == 'Lead') {
|
||||
data.quotation_name = repl('[%(quotation_to)s] %(lead_name)s', data);
|
||||
} else {
|
||||
data.quotation_name = repl('[%(quotation_to)s] %(customer_name)s', data);
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '3%', content:'docstatus'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '44%', content:'quotation_name+tags', css: {color:'#222'}},
|
||||
{
|
||||
width: '18%',
|
||||
content: function(parent, data) {
|
||||
$(parent).html(data.currency + ' ' + fmt_money(data.grand_total_export))
|
||||
},
|
||||
css: {'text-align':'right'}
|
||||
},
|
||||
{width: '12%', content:'transaction_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Quotation Date", type: "date"}
|
||||
]
|
||||
|
||||
});
|
||||
|
||||
1
selling/doctype/quotation_item/__init__.py
Normal file
1
selling/doctype/quotation_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
345
selling/doctype/quotation_item/quotation_item.txt
Normal file
345
selling/doctype/quotation_item/quotation_item.txt
Normal file
@@ -0,0 +1,345 @@
|
||||
# DocType, Quotation Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-06-08 16:07:57',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-09 11:04:47',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'QUOD/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'is_transaction_doc': 0,
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Quotation Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Quotation Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Quotation Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_item_code',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u"Customer's Item Code",
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Item Name',
|
||||
'oldfieldname': u'item_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Quantity',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate',
|
||||
'oldfieldname': u'ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'adj_rate',
|
||||
'fieldtype': u'Float',
|
||||
'label': u'Discount (%)',
|
||||
'oldfieldname': u'adj_rate',
|
||||
'oldfieldtype': u'Float',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'export_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Amount',
|
||||
'oldfieldname': u'export_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'base_ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate*',
|
||||
'oldfieldname': u'base_ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Basic Rate*',
|
||||
'oldfieldname': u'basic_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Amount*',
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Item Group',
|
||||
'oldfieldname': u'item_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item Group',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Brand',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_tax_rate',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 1,
|
||||
'label': u'Item Tax Rate',
|
||||
'oldfieldname': u'item_tax_rate',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Against Docname',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_doctype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Against Doctype',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_doctype',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 1,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'page_break',
|
||||
'fieldtype': u'Check',
|
||||
'hidden': 0,
|
||||
'label': u'Page Break',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'page_break',
|
||||
'oldfieldtype': u'Check',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,142 @@
|
||||
# DocType, Sales and Purchase Return Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:14',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:14',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'wasim@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 8
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales and Purchase Return Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Sales and Purchase Return Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales and Purchase Return Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'uom',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'UOM',
|
||||
'permlevel': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'returned_qty',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Returned Qty',
|
||||
'oldfieldname': u'returned_qty',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Serial No',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'batch_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Batch No',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'detail_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Detail Name',
|
||||
'oldfieldname': u'detail_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sales_common/__init__.py
Normal file
1
selling/doctype/sales_common/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
859
selling/doctype/sales_common/sales_common.js
Normal file
859
selling/doctype/sales_common/sales_common.js
Normal file
@@ -0,0 +1,859 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Preset
|
||||
// ------
|
||||
// cur_frm.cscript.tname - Details table name
|
||||
// cur_frm.cscript.fname - Details fieldname
|
||||
// cur_frm.cscript.other_fname - wn.require('erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js'); fieldname
|
||||
// cur_frm.cscript.sales_team_fname - Sales Team fieldname
|
||||
|
||||
// ============== Load Default Taxes ===================
|
||||
cur_frm.cscript.load_taxes = function(doc, cdt, cdn, callback) {
|
||||
// run if this is not executed from dt_map...
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if(doc.customer || getchildren('Sales Taxes and Charges', doc.name, 'other_charges', doc.doctype).length) {
|
||||
if(callback) {
|
||||
callback(doc, cdt, cdn);
|
||||
}
|
||||
} else {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'load_default_taxes','',function(r,rt){
|
||||
refresh_field('other_charges');
|
||||
if(callback) callback(doc, cdt, cdn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Gets called after existing item details are update to fill in
|
||||
// remaining default values
|
||||
cur_frm.cscript.load_defaults = function(doc, dt, dn, callback) {
|
||||
if(!cur_frm.doc.__islocal) { return; }
|
||||
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var fields_to_refresh = LocalDB.set_default_values(doc);
|
||||
if(fields_to_refresh) { refresh_many(fields_to_refresh); }
|
||||
|
||||
fields_to_refresh = null;
|
||||
var children = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(!children) { return; }
|
||||
for(var i=0; i<children.length; i++) {
|
||||
LocalDB.set_default_values(children[i]);
|
||||
}
|
||||
refresh_field(cur_frm.cscript.fname);
|
||||
cur_frm.cscript.load_taxes(doc, dt, dn, callback);
|
||||
}
|
||||
|
||||
|
||||
// Update existing item details
|
||||
cur_frm.cscript.update_item_details = function(doc, dt, dn, callback) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if(!cur_frm.doc.__islocal) return;
|
||||
var children = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(children.length) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name), 'get_item_details', '',
|
||||
function(r, rt) {
|
||||
if(!r.exc) {
|
||||
refresh_field(cur_frm.cscript.fname);
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
cur_frm.cscript.load_defaults(doc, dt, dn, callback);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cur_frm.cscript.load_taxes(doc, dt, dn, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var set_dynamic_label_par = function(doc, cdt, cdn, base_curr) {
|
||||
//parent flds
|
||||
par_cols_base = {'net_total': 'Net Total', 'other_charges_total': 'Taxes and Charges Total',
|
||||
'grand_total': 'Grand Total', 'rounded_total': 'Rounded Total', 'in_words': 'In Words'}
|
||||
par_cols_export = {'grand_total_export': 'Grand Total', 'rounded_total_export': 'Rounded Total', 'in_words_export': 'In Words'};
|
||||
|
||||
for (d in par_cols_base) cur_frm.fields_dict[d].label_span.innerHTML = par_cols_base[d]+' (' + base_curr + ')';
|
||||
for (d in par_cols_export) cur_frm.fields_dict[d].label_span.innerHTML = par_cols_export[d]+' (' + doc.currency + ')';
|
||||
cur_frm.fields_dict['conversion_rate'].label_span.innerHTML = "Conversion Rate (" + doc.currency +' -> '+ base_curr + ')';
|
||||
cur_frm.fields_dict['plc_conversion_rate'].label_span.innerHTML = 'Price List Currency Conversion Rate (' + doc.price_list_currency +' -> '+ base_curr + ')';
|
||||
|
||||
if (doc.doctype == 'Sales Invoice') {
|
||||
si_cols = {'total_advance': 'Total Advance', 'outstanding_amount': 'Outstanding Amount', 'paid_amount': 'Paid Amount', 'write_off_amount': 'Write Off Amount'}
|
||||
for (d in si_cols) cur_frm.fields_dict[d].label_span.innerHTML = si_cols[d] + ' (' + base_curr + ')';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var set_dynamic_label_child = function(doc, cdt, cdn, base_curr) {
|
||||
// item table flds
|
||||
item_cols_base = {'basic_rate': 'Basic Rate', 'base_ref_rate': 'Price List Rate', 'amount': 'Amount'};
|
||||
item_cols_export = {'export_rate': 'Basic Rate', 'ref_rate': 'Price List Rate', 'export_amount': 'Amount'};
|
||||
|
||||
for (d in item_cols_base) $('[data-grid-fieldname="'+cur_frm.cscript.tname+'-'+d+'"]').html(item_cols_base[d]+' ('+base_curr+')');
|
||||
for (d in item_cols_export) $('[data-grid-fieldname="'+cur_frm.cscript.tname+'-'+d+'"]').html(item_cols_export[d]+' ('+doc.currency+')');
|
||||
|
||||
var hide = (doc.currency == sys_defaults['currency']) ? false : true;
|
||||
for (f in item_cols_base) {
|
||||
cur_frm.fields_dict[cur_frm.cscript.fname].grid.set_column_disp(f, hide);
|
||||
}
|
||||
|
||||
//tax table flds
|
||||
tax_cols = {'tax_amount': 'Amount', 'total': 'Total'};
|
||||
for (d in tax_cols) $('[data-grid-fieldname="Sales Taxes and Charges-'+d+'"]').html(tax_cols[d]+' ('+base_curr+')');
|
||||
|
||||
if (doc.doctype == 'Sales Invoice') {
|
||||
// advance table flds
|
||||
adv_cols = {'advance_amount': 'Advance Amount', 'allocated_amount': 'Allocated Amount'}
|
||||
for (d in adv_cols) $('[data-grid-fieldname="Sales Invoice Advance-'+d+'"]').html(adv_cols[d]+' ('+base_curr+')');
|
||||
}
|
||||
}
|
||||
|
||||
// Change label dynamically based on currency
|
||||
//------------------------------------------------------------------
|
||||
|
||||
cur_frm.cscript.dynamic_label = function(doc, cdt, cdn, base_curr, callback) {
|
||||
cur_frm.cscript.base_currency = base_curr;
|
||||
set_dynamic_label_par(doc, cdt, cdn, base_curr);
|
||||
set_dynamic_label_child(doc, cdt, cdn, base_curr);
|
||||
set_sales_bom_help(doc);
|
||||
|
||||
if (callback) callback(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
// Help for Sales BOM items
|
||||
var set_sales_bom_help = function(doc) {
|
||||
if(!cur_frm.fields_dict.packing_list) return;
|
||||
if (getchildren('Delivery Note Packing Item', doc.name, 'packing_details').length) {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
|
||||
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
help_msg = "<div class='help-box'> \
|
||||
For 'Sales BOM' items, warehouse, serial no and batch no \
|
||||
will be considered from the 'Packing List' table. \
|
||||
If warehouse and batch no are same for all packing items for any 'Sales BOM' item, \
|
||||
those values can be entered in the main item table, values will be copied to 'Packing List' table. \
|
||||
</div>";
|
||||
wn.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
|
||||
}
|
||||
} else {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
wn.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = '';
|
||||
}
|
||||
}
|
||||
refresh_field('sales_bom_help');
|
||||
}
|
||||
|
||||
|
||||
// hide / unhide price list currency based on availability of price list in customer's currency
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
cur_frm.cscript.hide_price_list_currency = function(doc, cdt, cdn, callback1) {
|
||||
if (doc.price_list_name && doc.currency) {
|
||||
wn.call({
|
||||
method: 'selling.doctype.sales_common.sales_common.get_price_list_currency',
|
||||
args: {'price_list':doc.price_list_name, 'company': doc.company},
|
||||
callback: function(r, rt) {
|
||||
pl_currency = r.message[0]?r.message[0]:[];
|
||||
unhide_field(['price_list_currency', 'plc_conversion_rate']);
|
||||
|
||||
if (pl_currency.length==1) {
|
||||
if (doc.price_list_currency != pl_currency[0]) set_multiple(cdt, cdn, {price_list_currency:pl_currency[0]});
|
||||
if (pl_currency[0] == doc.currency) {
|
||||
if(doc.plc_conversion_rate != doc.conversion_rate) set_multiple(cdt, cdn, {plc_conversion_rate:doc.conversion_rate});
|
||||
hide_field(['price_list_currency', 'plc_conversion_rate']);
|
||||
} else if (pl_currency[0] == r.message[1]) {
|
||||
if (doc.plc_conversion_rate != 1) set_multiple(cdt, cdn, {plc_conversion_rate:1})
|
||||
hide_field(['price_list_currency', 'plc_conversion_rate']);
|
||||
}
|
||||
}
|
||||
|
||||
if (r.message[1] == doc.currency) {
|
||||
if (doc.conversion_rate != 1) set_multiple(cdt, cdn, {conversion_rate:1});
|
||||
hide_field(['conversion_rate', 'grand_total_export', 'in_words_export', 'rounded_total_export']);
|
||||
} else unhide_field(['conversion_rate', 'grand_total_export', 'in_words_export', 'rounded_total_export']);
|
||||
|
||||
if (r.message[1] == doc.price_list_currency) {
|
||||
if (doc.plc_conversion_rate != 1) set_multiple(cdt, cdn, {plc_conversion_rate:1});
|
||||
hide_field('plc_conversion_rate');
|
||||
} else unhide_field('plc_conversion_rate');
|
||||
|
||||
cur_frm.cscript.dynamic_label(doc, cdt, cdn, r.message[1], callback1);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TRIGGERS FOR CALCULATIONS
|
||||
// =====================================================================================================
|
||||
|
||||
// ********************* CURRENCY ******************************
|
||||
cur_frm.cscript.currency = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.price_list_name(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.price_list_currency = cur_frm.cscript.currency;
|
||||
cur_frm.cscript.conversion_rate = cur_frm.cscript.currency;
|
||||
cur_frm.cscript.plc_conversion_rate = cur_frm.cscript.currency;
|
||||
|
||||
cur_frm.cscript.company = function(doc, cdt, cdn) {
|
||||
wn.call({
|
||||
method: 'selling.doctype.sales_common.sales_common.get_comp_base_currency',
|
||||
args: {company:doc.company},
|
||||
callback: function(r, rt) {
|
||||
var doc = locals[cdt][cdn];
|
||||
set_multiple(doc.doctype, doc.name, {
|
||||
currency:r.message,
|
||||
price_list_currency:r.message
|
||||
});
|
||||
cur_frm.cscript.currency(doc, cdt, cdn);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ******************** PRICE LIST ******************************
|
||||
cur_frm.cscript.price_list_name = function(doc, cdt, cdn) {
|
||||
var callback = function() {
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var cl = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(doc.price_list_name && doc.currency && doc.price_list_currency && doc.conversion_rate && doc.plc_conversion_rate) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name), 'get_adj_percent', '',
|
||||
function(r, rt) {
|
||||
refresh_field(fname);
|
||||
var doc = locals[cdt][cdn];
|
||||
cur_frm.cscript.recalc(doc,3); //this is to re-calculate BASIC RATE and AMOUNT on basis of changed REF RATE
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn, callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ******************** ITEM CODE ********************************
|
||||
cur_frm.fields_dict[cur_frm.cscript.fname].grid.get_field("item_code").get_query = function(doc, cdt, cdn) {
|
||||
if (inList(['Maintenance', 'Service'], doc.order_type))
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description \
|
||||
FROM tabItem WHERE tabItem.is_service_item="Yes" \
|
||||
AND tabItem.docstatus != 2 \
|
||||
AND (ifnull(`tabItem`.`end_of_life`,"") = "" \
|
||||
OR `tabItem`.`end_of_life` > NOW() \
|
||||
OR `tabItem`.`end_of_life`="0000-00-00") \
|
||||
AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
else
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem \
|
||||
WHERE tabItem.is_sales_item="Yes" AND tabItem.docstatus != 2 \
|
||||
AND (ifnull(`tabItem`.`end_of_life`,"") = "" \
|
||||
OR `tabItem`.`end_of_life` > NOW() \
|
||||
OR `tabItem`.`end_of_life`="0000-00-00") \
|
||||
AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.item_code) {
|
||||
if (!doc.company) {
|
||||
msgprint("Please select company to proceed");
|
||||
d.item_code = '';
|
||||
refresh_field('item_code', d.name, fname);
|
||||
} else {
|
||||
var callback = function(r, rt){
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
var args = {
|
||||
'item_code':d.item_code,
|
||||
'income_account':d.income_account,
|
||||
'cost_center': d.cost_center,
|
||||
'warehouse': d.warehouse
|
||||
};
|
||||
get_server_fields('get_item_details',JSON.stringify(args),
|
||||
fname,doc,cdt,cdn,1,callback);
|
||||
}
|
||||
}
|
||||
if(cur_frm.cscript.custom_item_code){
|
||||
cur_frm.cscript.custom_item_code(doc, cdt, cdn);
|
||||
}
|
||||
}
|
||||
|
||||
//Barcode
|
||||
//
|
||||
cur_frm.cscript.barcode = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
var callback = function(r, rt) {
|
||||
cur_frm.cscript.item_code(doc, cdt, cdn);
|
||||
}
|
||||
get_server_fields('get_barcode_details', d.barcode, cur_frm.cscript.fname, doc, cdt, cdn, 1, callback);
|
||||
}
|
||||
|
||||
|
||||
// *********************** QUANTITY ***************************
|
||||
cur_frm.cscript.qty = function(doc, cdt, cdn) { cur_frm.cscript.recalc(doc, 1); }
|
||||
|
||||
// ************************ DISCOUNT (%) ***********************
|
||||
cur_frm.cscript.adj_rate = function(doc, cdt, cdn) { cur_frm.cscript.recalc(doc, 1); }
|
||||
|
||||
// ************************ REF RATE ****************************
|
||||
cur_frm.cscript.ref_rate = function(doc, cdt, cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, cur_frm.cscript.other_fname);
|
||||
if(!consider_incl_rate) {
|
||||
set_multiple(cur_frm.cscript.tname, d.name, {'export_rate': flt(d.ref_rate) * (100 - flt(d.adj_rate)) / 100}, cur_frm.cscript.fname);
|
||||
}
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
|
||||
// *********************** BASIC RATE **************************
|
||||
cur_frm.cscript.basic_rate = function(doc, cdt, cdn) {
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var d = locals[cdt][cdn];
|
||||
if(!d.qty) {
|
||||
d.qty = 1;
|
||||
refresh_field('qty', d.name, fname);
|
||||
}
|
||||
var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, cur_frm.cscript.other_fname);
|
||||
if(!consider_incl_rate) {
|
||||
cur_frm.cscript.recalc(doc, 2);
|
||||
} else {
|
||||
var basic_rate = cur_frm.cscript.back_calc_basic_rate(
|
||||
doc, cur_frm.cscript.tname, fname, d, cur_frm.cscript.other_fname
|
||||
);
|
||||
// TODO: remove roundNumber for basic_rate comparison
|
||||
if (d.basic_rate != roundNumber(basic_rate, 2)) {
|
||||
d.basic_rate = basic_rate;
|
||||
refresh_field('basic_rate', d.name, fname);
|
||||
msgprint("You cannot change Basic Rate* (Base Currency) when \
|
||||
considering rates inclusive of taxes.<br /> \
|
||||
Please either <br /> \
|
||||
* Specify Basic Rate (i.e. Rate which will be displayed in print) <br /> \
|
||||
-- or -- <br />\
|
||||
* Uncheck 'Is this Tax included in Basic Rate?' in the tax entries of Taxes section.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ************************ EXPORT RATE *************************
|
||||
cur_frm.cscript.export_rate = function(doc,cdt,cdn) {
|
||||
var cur_rec = locals[cdt][cdn];
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var tname = cur_frm.cscript.tname;
|
||||
if(flt(cur_rec.ref_rate)>0 && flt(cur_rec.export_rate)>0) {
|
||||
var adj_rate = 100 * (1 - (flt(cur_rec.export_rate) / flt(cur_rec.ref_rate)));
|
||||
set_multiple(tname, cur_rec.name, { 'adj_rate': adj_rate }, fname);
|
||||
}
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ************* GET OTHER CHARGES BASED ON COMPANY *************
|
||||
cur_frm.fields_dict.charge.get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabSales Taxes and Charges Master`.name FROM \
|
||||
`tabSales Taxes and Charges Master` WHERE `tabSales Taxes and Charges Master`.company = "'
|
||||
+doc.company+'" AND `tabSales Taxes and Charges Master`.company is not NULL \
|
||||
AND `tabSales Taxes and Charges Master`.docstatus != 2 \
|
||||
AND `tabSales Taxes and Charges Master`.%(key)s LIKE "%s" \
|
||||
ORDER BY `tabSales Taxes and Charges Master`.name LIMIT 50';
|
||||
}
|
||||
|
||||
// ********************* Get Charges ****************************
|
||||
cur_frm.cscript.get_charges = function(doc, cdt, cdn) {
|
||||
$c_obj(make_doclist(doc.doctype,doc.name),
|
||||
'get_other_charges',
|
||||
'',
|
||||
function(r, rt) { cur_frm.cscript.calculate_charges(doc, cdt, cdn);}
|
||||
,null,null,cur_frm.fields_dict.get_charges.input);
|
||||
}
|
||||
|
||||
|
||||
// CALCULATION OF TOTAL AMOUNTS
|
||||
// ========================================================================================================
|
||||
cur_frm.cscript.recalc = function(doc, n) {
|
||||
if(!n)n=0;
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var tname = cur_frm.cscript.tname;
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var sales_team = cur_frm.cscript.sales_team_fname;
|
||||
var other_fname = cur_frm.cscript.other_fname;
|
||||
|
||||
if(!flt(doc.conversion_rate)) {
|
||||
doc.conversion_rate = 1;
|
||||
refresh_field('conversion_rate');
|
||||
}
|
||||
if(!flt(doc.plc_conversion_rate)) {
|
||||
doc.plc_conversion_rate = 1;
|
||||
refresh_field('plc_conversion_rate');
|
||||
}
|
||||
|
||||
if(n > 0) cur_frm.cscript.update_fname_table(doc , tname , fname , n, other_fname); // updates all values in table (i.e. amount, export amount, net total etc.)
|
||||
|
||||
if(flt(doc.net_total) > 0) {
|
||||
var cl = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
cl[i].total_tax_amount = 0;
|
||||
cl[i].total_amount = 0;
|
||||
cl[i].tax_amount = 0; // this is done to calculate other charges
|
||||
cl[i].total = 0;
|
||||
cl[i].item_wise_tax_detail = "";
|
||||
if(in_list(['On Previous Row Amount','On Previous Row Total'],cl[i].charge_type) && !cl[i].row_id){
|
||||
alert("Please Enter Row on which amount needs to be calculated for row : "+cl[i].idx);
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.calc_other_charges(doc , tname , fname , other_fname); // calculate other charges
|
||||
}
|
||||
cur_frm.cscript.calc_doc_values(doc, null, null, tname, fname, other_fname); // calculates total amounts
|
||||
|
||||
// ******************* calculate allocated amount of sales person ************************
|
||||
cl = getchildren('Sales Team', doc.name, sales_team);
|
||||
for(var i=0;i<cl.length;i++) {
|
||||
if (cl[i].allocated_percentage) {
|
||||
cl[i].allocated_amount = flt(flt(doc.net_total)*flt(cl[i].allocated_percentage)/100);
|
||||
refresh_field('allocated_amount', cl[i].name, sales_team);
|
||||
}
|
||||
}
|
||||
doc.in_words = '';
|
||||
doc.in_words_export = '';
|
||||
refresh_many(['total_discount_rate','total_discount','net_total','total_commission','grand_total','rounded_total','grand_total_export','rounded_total_export','in_words','in_words_export','other_charges','other_charges_total']);
|
||||
if(cur_frm.cscript.custom_recalc)cur_frm.cscript.custom_recalc(doc);
|
||||
}
|
||||
|
||||
// ******* Calculation of total amounts of document (item amount + other charges)****************
|
||||
cur_frm.cscript.calc_doc_values = function(doc, cdt, cdn, tname, fname, other_fname) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var net_total = 0; var other_charges_total = 0;
|
||||
var net_total_incl = 0
|
||||
var cl = getchildren(tname, doc.name, fname);
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
//net_total += flt(cl[i].basic_rate) * flt(cl[i].qty);
|
||||
net_total += flt(cl[i].amount);
|
||||
net_total_incl += flt(cl[i].export_amount);
|
||||
}
|
||||
|
||||
var inclusive_rate = 0
|
||||
var d = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
for(var j = 0; j<d.length; j++){
|
||||
other_charges_total += flt(d[j].tax_amount);
|
||||
if(d[j].included_in_print_rate) {
|
||||
inclusive_rate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(flt(doc.conversion_rate)>1) {
|
||||
net_total_incl *= flt(doc.conversion_rate);
|
||||
}
|
||||
|
||||
doc.net_total = inclusive_rate ? flt(net_total_incl) : flt(net_total);
|
||||
doc.other_charges_total = roundNumber(flt(other_charges_total), 2);
|
||||
doc.grand_total = roundNumber((flt(net_total) + flt(other_charges_total)), 2);
|
||||
doc.rounded_total = Math.round(doc.grand_total);
|
||||
doc.grand_total_export = roundNumber((flt(doc.grand_total) / flt(doc.conversion_rate)), 2);
|
||||
doc.rounded_total_export = Math.round(doc.grand_total_export);
|
||||
doc.total_commission = flt(flt(net_total) * flt(doc.commission_rate) / 100);
|
||||
}
|
||||
|
||||
// ******************************* OTHER CHARGES *************************************
|
||||
cur_frm.cscript.calc_other_charges = function(doc , tname , fname , other_fname) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
|
||||
// Make Display Area
|
||||
cur_frm.fields_dict['other_charges_calculation'].disp_area.innerHTML =
|
||||
'<b style="padding: 8px 0px;">Calculation Details for Taxes and Charges:</b>';
|
||||
|
||||
var cl = getchildren(tname, doc.name, fname);
|
||||
var tax = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
|
||||
// Make display table
|
||||
var otc = make_table(cur_frm.fields_dict['other_charges_calculation'].disp_area,
|
||||
cl.length + 1, tax.length + 1, '90%', [], { border:'1px solid #AAA', padding:'2px' });
|
||||
$y(otc,{marginTop:'8px'});
|
||||
|
||||
var tax_desc = {}; var tax_desc_rates = []; var net_total = 0;
|
||||
|
||||
for(var i=0;i<cl.length;i++) {
|
||||
net_total += flt(flt(cl[i].qty) * flt(cl[i].basic_rate));
|
||||
var prev_total = flt(cl[i].amount);
|
||||
if(cl[i].item_tax_rate) {
|
||||
try {
|
||||
var check_tax = JSON.parse(cl[i].item_tax_rate); //to get in dictionary
|
||||
} catch(exception) {
|
||||
var check_tax = eval('var a='+cl[i].item_tax_rate+';a'); //to get in dictionary
|
||||
}
|
||||
}
|
||||
|
||||
// Add Item Code in new Row
|
||||
$td(otc,i+1,0).innerHTML = cl[i].item_code ? cl[i].item_code : cl[i].description;
|
||||
|
||||
//var tax = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
var total = net_total;
|
||||
|
||||
|
||||
for(var t=0;t<tax.length;t++){
|
||||
var account = tax[t].account_head;
|
||||
$td(otc,0,t+1).innerHTML = account?account:'';
|
||||
//Check For Rate
|
||||
if(cl[i].item_tax_rate && check_tax[account]!=null) {
|
||||
var rate = flt(check_tax[account]);
|
||||
} else {
|
||||
// if particular item doesn't have particular rate it will take other charges rate
|
||||
var rate = flt(tax[t].rate);
|
||||
}
|
||||
|
||||
//Check For Rate and get tax amount
|
||||
var tax_amount = cur_frm.cscript.check_charge_type_and_get_tax_amount(doc,tax,t, cl[i], rate);
|
||||
|
||||
//enter item_wise_tax_detail i.e. tax rate on each item
|
||||
var item_wise_tax_detail = cur_frm.cscript.get_item_wise_tax_detail(doc, rate, cl, i, tax, t);
|
||||
if(tax[t].charge_type != "Actual") tax[t].item_wise_tax_detail += item_wise_tax_detail;
|
||||
tax[t].total_amount = flt(tax_amount); //stores actual tax amount in virtual field
|
||||
tax[t].total_tax_amount = flt(prev_total); //stores total amount in virtual field
|
||||
tax[t].tax_amount += flt(tax_amount);
|
||||
var total_amount = flt(tax[t].tax_amount);
|
||||
total_tax_amount = flt(tax[t].total_tax_amount) + flt(total_amount);
|
||||
set_multiple('Sales Taxes and Charges', tax[t].name, { 'item_wise_tax_detail':tax[t].item_wise_tax_detail, 'amount':roundNumber(flt(total_amount), 2), 'total':roundNumber(flt(total)+flt(tax[t].tax_amount), 2)}, other_fname);
|
||||
prev_total += flt(tax[t].total_amount); // for previous row total
|
||||
total += flt(tax[t].tax_amount); // for adding total to previous amount
|
||||
|
||||
if(tax[t].charge_type == 'Actual')
|
||||
$td(otc,i+1,t+1).innerHTML = fmt_money(tax[t].total_amount);
|
||||
else
|
||||
$td(otc,i+1,t+1).innerHTML = '('+fmt_money(rate) + '%) ' +fmt_money(tax[t].total_amount);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for(var t=0;t<tax.length;t++){
|
||||
tax[t].tax_amount = roundNumber(tax[t].tax_amount, 2);
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.check_charge_type_and_get_tax_amount = function( doc, tax, t, cl, rate, print_amt) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if (! print_amt) print_amt = 0;
|
||||
var tax_amount = 0;
|
||||
if(tax[t].charge_type == 'Actual') {
|
||||
var value = flt(tax[t].rate) / flt(doc.net_total); // this give the ratio in which all items are divided
|
||||
return tax_amount = flt(value) * flt(cl.amount);
|
||||
}
|
||||
else if(tax[t].charge_type == 'On Net Total') {
|
||||
if (flt(print_amt) == 1) {
|
||||
doc.excise_rate = flt(rate);
|
||||
doc.total_excise_rate += flt(rate);
|
||||
refresh_field('excise_rate');
|
||||
refresh_field('total_excise_rate');
|
||||
return
|
||||
}
|
||||
return tax_amount = (flt(rate) * flt(cl.amount) / 100);
|
||||
}
|
||||
else if(tax[t].charge_type == 'On Previous Row Amount'){
|
||||
if(flt(print_amt) == 1) {
|
||||
doc.total_excise_rate += flt(flt(doc.excise_rate) * 0.01 * flt(rate));
|
||||
refresh_field('total_excise_rate');
|
||||
return
|
||||
}
|
||||
var row_no = (tax[t].row_id).toString();
|
||||
var row = (row_no).split("+"); // splits the values and stores in an array
|
||||
for(var r = 0;r<row.length;r++){
|
||||
var id = cint(row[r].replace(/^\s+|\s+$/g,""));
|
||||
tax_amount += (flt(rate) * flt(tax[id-1].total_amount) / 100);
|
||||
}
|
||||
var row_id = row_no.indexOf("/");
|
||||
if(row_id != -1) {
|
||||
rate = '';
|
||||
var row = (row_no).split("/"); // splits the values and stores in an array
|
||||
if(row.length>2) alert("You cannot enter more than 2 nos. for division");
|
||||
var id1 = cint(row[0].replace(/^\s+|\s+$/g,""));
|
||||
var id2 = cint(row[1].replace(/^\s+|\s+$/g,""));
|
||||
tax_amount = flt(tax[id1-1].total_amount) / flt(tax[id2-1].total_amount);
|
||||
}
|
||||
return tax_amount
|
||||
}
|
||||
else if(tax[t].charge_type == 'On Previous Row Total') {
|
||||
if(flt(print_amt) == 1) {
|
||||
doc.sales_tax_rate += flt(rate);
|
||||
refresh_field('sales_tax_rate');
|
||||
return
|
||||
}
|
||||
var row = cint(tax[t].row_id);
|
||||
return tax_amount = flt(rate) * (flt(tax[row-1].total_tax_amount)+flt(tax[row-1].total_amount)) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
// ********************** Functions for inclusive value calc ******************************
|
||||
cur_frm.cscript.consider_incl_rate = function(doc, other_fname) {
|
||||
var tax_list = getchildren('Sales Taxes and Charges', doc.name, other_fname, doc.doctype);
|
||||
for(var i=0; i<tax_list.length; i++) {
|
||||
if(tax_list[i].included_in_print_rate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cur_frm.cscript.back_calc_basic_rate = function(doc, tname, fname, child, other_fname) {
|
||||
var get_item_tax_rate = function(item, tax) {
|
||||
if(item.item_tax_rate) {
|
||||
try {
|
||||
var item_tax = JSON.parse(item.item_tax_rate);
|
||||
} catch(exception) {
|
||||
var item_tax = eval('var a='+item.item_tax_rate+';a');
|
||||
}
|
||||
if(item_tax[tax.account_head]!=null) {
|
||||
return flt(item_tax[tax.account_head]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var tax_list = getchildren('Sales Taxes and Charges', doc.name, other_fname, doc.doctype);
|
||||
var total = 1;
|
||||
var temp_tax_list = [];
|
||||
var amt = 0;
|
||||
var item_tax_rate = 0;
|
||||
var rate = 0;
|
||||
for(var i=0; i<tax_list.length; i++) {
|
||||
amt = 0;
|
||||
item_tax_rate = get_item_tax_rate(child, tax_list[i]);
|
||||
rate = item_tax_rate ? item_tax_rate : flt(tax_list[i].rate);
|
||||
if(tax_list[i].included_in_print_rate) {
|
||||
if(tax_list[i].charge_type=='On Net Total') {
|
||||
amt = flt(rate / 100);
|
||||
} else if(tax_list[i].charge_type=='On Previous Row Total') {
|
||||
amt = flt((rate * temp_tax_list[tax_list[i].row_id-1]['total']) / 100);
|
||||
} else if(tax_list[i].charge_type=='On Previous Row Amount') {
|
||||
amt = flt((rate * temp_tax_list[tax_list[i].row_id-1]['amt']) / 100);
|
||||
}
|
||||
}
|
||||
total += flt(amt);
|
||||
temp_tax_list[i] = {
|
||||
amt: amt,
|
||||
total: total
|
||||
};
|
||||
}
|
||||
var basic_rate = (child.export_rate * flt(doc.conversion_rate)) / total;
|
||||
//console.log(temp_tax_list);
|
||||
//console.log('in basic rate back calc');
|
||||
//console.log(basic_rate);
|
||||
return basic_rate;
|
||||
}
|
||||
|
||||
cur_frm.cscript.included_in_print_rate = function(doc, cdt, cdn) {
|
||||
var tax = locals[cdt][cdn];
|
||||
if(tax.included_in_print_rate==1) {
|
||||
if(!inList(['On Net Total', 'On Previous Row Total', 'On Previous Row Amount'], tax.charge_type)) {
|
||||
msgprint("'Is this Tax included in Basic Rate?' (i.e. Inclusive Price) is only valid for charges of type: <br /> \
|
||||
* On Net Total <br /> \
|
||||
* On Previous Row Amount <br /> \
|
||||
* On Previous Row Total");
|
||||
tax.included_in_print_rate = 0;
|
||||
refresh_field('included_in_print_rate', tax.name, cur_frm.cscript.other_fname);
|
||||
}
|
||||
var tax_list = getchildren('Sales Taxes and Charges', doc.name, cur_frm.cscript.other_fname, doc.doctype);
|
||||
cur_frm.cscript.validate_print_rate_option(doc, tax_list, tax.idx-1);
|
||||
}
|
||||
}
|
||||
|
||||
// ********************** Update values in table ******************************
|
||||
cur_frm.cscript.update_fname_table = function(doc , tname , fname , n, other_fname) {
|
||||
doc = locals[doc.doctype][doc.name]
|
||||
var net_total = 0
|
||||
var cl = getchildren(tname, doc.name, fname);
|
||||
var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, other_fname);
|
||||
for(var i=0;i<cl.length;i++) {
|
||||
if(n == 1){
|
||||
if(!consider_incl_rate) {
|
||||
if(flt(cl[i].ref_rate) > 0) {
|
||||
set_multiple(tname, cl[i].name, {
|
||||
'export_rate': flt(flt(cl[i].ref_rate) * (100 - flt(cl[i].adj_rate)) / 100)
|
||||
}, fname);
|
||||
}
|
||||
set_multiple(tname, cl[i].name, {
|
||||
'export_amount': flt(flt(cl[i].qty) * flt(cl[i].export_rate)),
|
||||
'basic_rate': flt(flt(cl[i].export_rate) * flt(doc.conversion_rate)),
|
||||
'amount': roundNumber(flt((flt(cl[i].export_rate) * flt(doc.conversion_rate)) * flt(cl[i].qty)), 2)
|
||||
}, fname);
|
||||
//var base_ref_rate = flt(cl[i].basic_rate) + flt(flt(cl[i].basic_rate) * flt(cl[i].adj_rate) / 100);
|
||||
//set_multiple(tname, cl[i].name, {
|
||||
// 'base_ref_rate': flt(base_ref_rate)
|
||||
//}, fname);
|
||||
|
||||
} else if(consider_incl_rate) {
|
||||
if(flt(cl[i].export_rate) > 0) {
|
||||
// calculate basic rate based on taxes
|
||||
// then calculate and set basic_rate, base_ref_rate, ref_rate, amount, export_amount
|
||||
var ref_rate = flt(cl[i].adj_rate)!=flt(100) ?
|
||||
flt((100 * flt(cl[i].export_rate))/flt(100 - flt(cl[i].adj_rate))) :
|
||||
flt(0)
|
||||
set_multiple(tname, cl[i].name, { 'ref_rate': ref_rate }, fname);
|
||||
} else if((flt(cl[i].ref_rate) > 0) && (flt(cl[i].adj_rate) > 0)) {
|
||||
var export_rate = flt(cl[i].ref_rate) * flt(1 - flt(cl[i].adj_rate / 100));
|
||||
set_multiple(tname, cl[i].name, { 'export_rate': flt(export_rate) }, fname);
|
||||
}
|
||||
//console.log("export_rate: " + cl[i].export_rate);
|
||||
|
||||
var basic_rate = cur_frm.cscript.back_calc_basic_rate(doc, tname, fname, cl[i], other_fname);
|
||||
var base_ref_rate = basic_rate + flt(basic_rate * flt(cl[i].adj_rate) / 100);
|
||||
set_multiple(tname, cl[i].name, {
|
||||
'basic_rate': flt(basic_rate),
|
||||
'amount': roundNumber(flt(basic_rate * flt(cl[i].qty)), 2),
|
||||
'export_amount': flt(flt(cl[i].qty) * flt(cl[i].export_rate)),
|
||||
'base_ref_rate': flt(base_ref_rate)
|
||||
}, fname);
|
||||
}
|
||||
}
|
||||
else if(n == 2){
|
||||
if(flt(cl[i].ref_rate) > 0)
|
||||
set_multiple(tname, cl[i].name, {'adj_rate': 100 - flt(flt(cl[i].basic_rate) * 100 / (flt(cl[i].ref_rate) * flt(doc.conversion_rate)))}, fname);
|
||||
set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(cl[i].basic_rate)), 'export_rate': flt(flt(cl[i].basic_rate) / flt(doc.conversion_rate)), 'export_amount': flt((flt(cl[i].basic_rate) / flt(doc.conversion_rate)) * flt(cl[i].qty)) }, fname);
|
||||
}
|
||||
/*else if(n == 3){
|
||||
set_multiple(tname, cl[i].name, {'basic_rate': flt(flt(cl[i].export_rate) * flt(doc.conversion_rate))}, fname);
|
||||
set_multiple(tname, cl[i].name, {'amount' : flt(flt(cl[i].basic_rate) * flt(cl[i].qty)), 'export_amount': flt(flt(cl[i].export_rate) * flt(cl[i].qty))}, fname);
|
||||
if(cl[i].ref_rate > 0)
|
||||
set_multiple(tname, cl[i].name, {'adj_rate': 100 - flt(flt(cl[i].export_rate) * 100 / flt(cl[i].ref_rate)), 'base_ref_rate': flt(flt(cl[i].ref_rate) * flt(doc.conversion_rate)) }, fname);
|
||||
}*/
|
||||
net_total += flt(flt(cl[i].qty) * flt(cl[i].basic_rate));
|
||||
}
|
||||
doc.net_total = net_total;
|
||||
refresh_field('net_total');
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_item_wise_tax_detail = function( doc, rate, cl, i, tax, t) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var detail = '';
|
||||
detail = cl[i].item_code + " : " + cstr(rate) + NEWLINE;
|
||||
return detail;
|
||||
}
|
||||
|
||||
// **************** RE-CALCULATE VALUES ***************************
|
||||
|
||||
cur_frm.cscript.recalculate_values = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.calculate_charges(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.validate_print_rate_option = function(doc, taxes, i) {
|
||||
if(in_list(['On Previous Row Amount','On Previous Row Total'], taxes[i].charge_type)) {
|
||||
if(!taxes[i].row_id){
|
||||
alert("Please Enter Row on which amount needs to be calculated for row : "+taxes[i].idx);
|
||||
validated = false;
|
||||
} else if(taxes[i].included_in_print_rate && taxes[taxes[i].row_id-1].charge_type=='Actual') {
|
||||
msgprint("Row of type 'Actual' cannot be depended on for type '" + taxes[i].charge_type + "'\
|
||||
when using tax inclusive prices.<br />\
|
||||
This will lead to incorrect values.<br /><br /> \
|
||||
<b>Please specify correct value in 'Enter Row' column of <span style='color:red'>Row: "
|
||||
+ taxes[i].idx + "</span> in Taxes table</b>");
|
||||
validated = false;
|
||||
taxes[i].included_in_print_rate = 0;
|
||||
refresh_field('included_in_print_rate', taxes[i].name, other_fname);
|
||||
} else if ((taxes[i].included_in_print_rate && !taxes[taxes[i].row_id-1].included_in_print_rate) ||
|
||||
(!taxes[i].included_in_print_rate && taxes[taxes[i].row_id-1].included_in_print_rate)) {
|
||||
msgprint("If any row in the tax table depends on 'Previous Row Amount/Total', <br />\
|
||||
'Is this Tax included in Basic Rate?' column should be same for both row <br />\
|
||||
i.e for that row and the previous row. <br /><br />\
|
||||
The same is violated for row #"+(i+1)+" and row #"+taxes[i].row_id
|
||||
);
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.calculate_charges = function(doc, cdt, cdn) {
|
||||
var other_fname = cur_frm.cscript.other_fname;
|
||||
|
||||
var cl = getchildren('Sales Taxes and Charges', doc.name, other_fname, doc.doctype);
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
cl[i].total_tax_amount = 0;
|
||||
cl[i].total_amount = 0;
|
||||
cl[i].tax_amount = 0; // this is done to calculate other charges
|
||||
cl[i].total = 0;
|
||||
cur_frm.cscript.validate_print_rate_option(doc, cl, i);
|
||||
}
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
|
||||
// Get Sales Partner Commission
|
||||
// =================================================================================
|
||||
cur_frm.cscript.sales_partner = function(doc, cdt, cdn){
|
||||
if(doc.sales_partner){
|
||||
|
||||
get_server_fields('get_comm_rate', doc.sales_partner, '', doc, cdt, cdn, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// *******Commission Rate Trigger (calculates total commission amount)*********
|
||||
cur_frm.cscript.commission_rate = function(doc, cdt, cdn) {
|
||||
if(doc.commission_rate > 100){
|
||||
alert("Commision rate cannot be greater than 100.");
|
||||
doc.total_commission = 0;
|
||||
doc.commission_rate = 0;
|
||||
}
|
||||
else
|
||||
doc.total_commission = doc.net_total * doc.commission_rate / 100;
|
||||
refresh_many(['total_commission','commission_rate']);
|
||||
|
||||
}
|
||||
|
||||
// *******Total Commission Trigger (calculates commission rate)*********
|
||||
cur_frm.cscript.total_commission = function(doc, cdt, cdn) {
|
||||
if(doc.net_total){
|
||||
if(doc.net_total < doc.total_commission){
|
||||
alert("Total commission cannot be greater than net total.");
|
||||
doc.total_commission = 0;
|
||||
doc.commission_rate = 0;
|
||||
}
|
||||
else
|
||||
doc.commission_rate = doc.total_commission * 100 / doc.net_total;
|
||||
refresh_many(['total_commission','commission_rate']);
|
||||
}
|
||||
}
|
||||
// Sales Person Allocated % trigger
|
||||
// ==============================================================================
|
||||
cur_frm.cscript.allocated_percentage = function(doc, cdt, cdn) {
|
||||
var fname = cur_frm.cscript.sales_team_fname;
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.allocated_percentage) {
|
||||
d.allocated_amount = flt(flt(doc.net_total)*flt(d.allocated_percentage)/100);
|
||||
refresh_field('allocated_amount', d.name, fname);
|
||||
}
|
||||
}
|
||||
|
||||
// Client Side Validation
|
||||
// =================================================================================
|
||||
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.validate_items(doc);
|
||||
var cl = getchildren('Sales Taxes and Charges Master', doc.name, 'other_charges');
|
||||
for(var i =0;i<cl.length;i++) {
|
||||
if(!cl[i].amount) {
|
||||
alert("Please Enter Amount in Row no. "+cl[i].idx+" in Taxes and Charges table");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.calculate_charges (doc, cdt, cdn);
|
||||
|
||||
if (cur_frm.cscript.calc_adjustment_amount) cur_frm.cscript.calc_adjustment_amount(doc);
|
||||
}
|
||||
|
||||
|
||||
// ************** Atleast one item in document ****************
|
||||
cur_frm.cscript.validate_items = function(doc) {
|
||||
var cl = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(!cl.length){
|
||||
alert("Please enter Items for " + doc.doctype);
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
904
selling/doctype/sales_common/sales_common.py
Normal file
904
selling/doctype/sales_common/sales_common.py
Normal file
@@ -0,0 +1,904 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_comp_base_currency(arg=None):
|
||||
""" get default currency of company"""
|
||||
res = webnotes.conn.sql("""select default_currency from `tabCompany`
|
||||
where name = %s""", webnotes.form_dict.get('company'))
|
||||
return res and res[0][0] or None
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_price_list_currency(arg=None):
|
||||
""" Get all currency in which price list is maintained"""
|
||||
plc = webnotes.conn.sql("select distinct ref_currency from `tabItem Price` where price_list_name = %s", webnotes.form_dict['price_list'])
|
||||
plc = [d[0] for d in plc]
|
||||
base_currency = get_comp_base_currency(webnotes.form_dict['company'])
|
||||
return plc, base_currency
|
||||
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d,dl
|
||||
|
||||
self.doctype_dict = {
|
||||
'Sales Order' : 'Sales Order Item',
|
||||
'Delivery Note' : 'Delivery Note Item',
|
||||
'Sales Invoice':'Sales Invoice Item',
|
||||
'Installation Note' : 'Installation Note Item'
|
||||
}
|
||||
|
||||
self.ref_doctype_dict= {}
|
||||
|
||||
self.next_dt_detail = {
|
||||
'delivered_qty' : 'Delivery Note Item',
|
||||
'billed_qty' : 'Sales Invoice Item',
|
||||
'installed_qty' : 'Installation Note Item'}
|
||||
|
||||
self.msg = []
|
||||
|
||||
|
||||
# Get Sales Person Details
|
||||
# ==========================
|
||||
|
||||
# TODO: To be deprecated if not in use
|
||||
def get_sales_person_details(self, obj):
|
||||
if obj.doc.doctype != 'Quotation':
|
||||
obj.doclist = obj.doc.clear_table(obj.doclist,'sales_team')
|
||||
idx = 0
|
||||
for d in webnotes.conn.sql("select sales_person, allocated_percentage, allocated_amount, incentives from `tabSales Team` where parent = '%s'" % obj.doc.customer):
|
||||
ch = addchild(obj.doc, 'sales_team', 'Sales Team', 1, obj.doclist)
|
||||
ch.sales_person = d and cstr(d[0]) or ''
|
||||
ch.allocated_percentage = d and flt(d[1]) or 0
|
||||
ch.allocated_amount = d and flt(d[2]) or 0
|
||||
ch.incentives = d and flt(d[3]) or 0
|
||||
ch.idx = idx
|
||||
idx += 1
|
||||
return obj.doclist
|
||||
|
||||
|
||||
# Get customer's contact person details
|
||||
# ==============================================================
|
||||
def get_contact_details(self, obj = '', primary = 0):
|
||||
cond = " and contact_name = '"+cstr(obj.doc.contact_person)+"'"
|
||||
if primary: cond = " and is_primary_contact = 'Yes'"
|
||||
contact = webnotes.conn.sql("select contact_name, contact_no, email_id, contact_address from `tabContact` where customer = '%s' and docstatus != 2 %s" %(obj.doc.customer, cond), as_dict = 1)
|
||||
if not contact:
|
||||
return
|
||||
c = contact[0]
|
||||
obj.doc.contact_person = c['contact_name'] or ''
|
||||
obj.doc.contact_no = c['contact_no'] or ''
|
||||
obj.doc.email_id = c['email_id'] or ''
|
||||
obj.doc.customer_mobile_no = c['contact_no'] or ''
|
||||
if c['contact_address']:
|
||||
obj.doc.customer_address = c['contact_address']
|
||||
|
||||
|
||||
# Get customer's primary shipping details
|
||||
# ==============================================================
|
||||
def get_shipping_details(self, obj = ''):
|
||||
det = webnotes.conn.sql("select name, ship_to, shipping_address from `tabShipping Address` where customer = '%s' and docstatus != 2 and ifnull(is_primary_address, 'Yes') = 'Yes'" %(obj.doc.customer), as_dict = 1)
|
||||
obj.doc.ship_det_no = det and det[0]['name'] or ''
|
||||
obj.doc.ship_to = det and det[0]['ship_to'] or ''
|
||||
obj.doc.shipping_address = det and det[0]['shipping_address'] or ''
|
||||
|
||||
|
||||
# get invoice details
|
||||
# ====================
|
||||
def get_invoice_details(self, obj = ''):
|
||||
if obj.doc.company:
|
||||
acc_head = webnotes.conn.sql("select name from `tabAccount` where name = '%s' and docstatus != 2" % (cstr(obj.doc.customer) + " - " + get_value('Company', obj.doc.company, 'abbr')))
|
||||
obj.doc.debit_to = acc_head and acc_head[0][0] or ''
|
||||
|
||||
|
||||
|
||||
# Get Item Details
|
||||
# ===============================================================
|
||||
def get_item_details(self, args, obj):
|
||||
import json
|
||||
if not obj.doc.price_list_name:
|
||||
msgprint("Please Select Price List before selecting Items")
|
||||
raise Exception
|
||||
item = webnotes.conn.sql("select description, item_name, brand, item_group, stock_uom, default_warehouse, default_income_account, default_sales_cost_center, description_html, barcode from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life > now() or end_of_life = '0000-00-00') and (is_sales_item = 'Yes' or is_service_item = 'Yes')" % (args['item_code']), as_dict=1)
|
||||
tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , args['item_code'])
|
||||
t = {}
|
||||
for x in tax: t[x[0]] = flt(x[1])
|
||||
ret = {
|
||||
'description' : item and item[0]['description_html'] or item[0]['description'],
|
||||
'barcode' : item and item[0]['barcode'] or '',
|
||||
'item_group' : item and item[0]['item_group'] or '',
|
||||
'item_name' : item and item[0]['item_name'] or '',
|
||||
'brand' : item and item[0]['brand'] or '',
|
||||
'stock_uom' : item and item[0]['stock_uom'] or '',
|
||||
'reserved_warehouse' : item and item[0]['default_warehouse'] or '',
|
||||
'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'),
|
||||
'income_account' : item and item[0]['default_income_account'] or args.get('income_account'),
|
||||
'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center'),
|
||||
'qty' : 1.00, # this is done coz if item once fetched is fetched again thn its qty shld be reset to 1
|
||||
'adj_rate' : 0,
|
||||
'amount' : 0,
|
||||
'export_amount' : 0,
|
||||
'item_tax_rate' : json.dumps(t),
|
||||
'batch_no' : ''
|
||||
}
|
||||
if(obj.doc.price_list_name and item): #this is done to fetch the changed BASIC RATE and REF RATE based on PRICE LIST
|
||||
base_ref_rate = self.get_ref_rate(args['item_code'], obj.doc.price_list_name, obj.doc.price_list_currency, obj.doc.plc_conversion_rate)
|
||||
ret['ref_rate'] = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
ret['export_rate'] = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
ret['base_ref_rate'] = flt(base_ref_rate)
|
||||
ret['basic_rate'] = flt(base_ref_rate)
|
||||
|
||||
if ret['warehouse'] or ret['reserved_warehouse']:
|
||||
av_qty = self.get_available_qty({'item_code': args['item_code'], 'warehouse': ret['warehouse'] or ret['reserved_warehouse']})
|
||||
ret.update(av_qty)
|
||||
|
||||
# get customer code for given item from Item Customer Detail
|
||||
customer_item_code_row = webnotes.conn.sql("""\
|
||||
select ref_code from `tabItem Customer Detail`
|
||||
where parent = %s and customer_name = %s""",
|
||||
(args['item_code'], obj.doc.customer))
|
||||
if customer_item_code_row and customer_item_code_row[0][0]:
|
||||
ret['customer_item_code'] = customer_item_code_row[0][0]
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def get_item_defaults(self, args):
|
||||
item = webnotes.conn.sql("""select default_warehouse, default_income_account, default_sales_cost_center from `tabItem`
|
||||
where name = '%s' and (ifnull(end_of_life,'') = '' or end_of_life > now() or end_of_life = '0000-00-00')
|
||||
and (is_sales_item = 'Yes' or is_service_item = 'Yes') """ % (args['item_code']), as_dict=1)
|
||||
ret = {
|
||||
'reserved_warehouse' : item and item[0]['default_warehouse'] or '',
|
||||
'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'),
|
||||
'income_account' : item and item[0]['default_income_account'] or args.get('income_account'),
|
||||
'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center')
|
||||
}
|
||||
|
||||
return ret
|
||||
|
||||
def get_available_qty(self,args):
|
||||
tot_avail_qty = webnotes.conn.sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
|
||||
ret = {
|
||||
'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0,
|
||||
'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
# ***************** Get Ref rate as entered in Item Master ********************
|
||||
def get_ref_rate(self, item_code, price_list_name, price_list_currency, plc_conv_rate):
|
||||
ref_rate = webnotes.conn.sql("select ref_rate from `tabItem Price` where parent = %s and price_list_name = %s and ref_currency = %s", (item_code, price_list_name, price_list_currency))
|
||||
base_ref_rate = ref_rate and flt(ref_rate[0][0]) * flt(plc_conv_rate) or 0
|
||||
return base_ref_rate
|
||||
|
||||
def get_barcode_details(self, barcode):
|
||||
item = webnotes.conn.sql("select name, end_of_life, is_sales_item, is_service_item \
|
||||
from `tabItem` where barcode = %s", barcode, as_dict=1)
|
||||
ret = {}
|
||||
if not item:
|
||||
msgprint("""No item found for this barcode: %s.
|
||||
May be barcode not updated in item master. Please check""" % barcode)
|
||||
elif item[0]['end_of_life'] and getdate(cstr(item[0]['end_of_life'])) < nowdate():
|
||||
msgprint("Item: %s has been expired. Please check 'End of Life' field in item master" % item[0]['name'])
|
||||
elif item[0]['is_sales_item'] == 'No' and item[0]['is_service_item'] == 'No':
|
||||
msgprint("Item: %s is not a sales or service item" % item[0]['name'])
|
||||
elif len(item) > 1:
|
||||
msgprint("There are multiple item for this barcode. \nPlease select item code manually")
|
||||
else:
|
||||
ret = {'item_code': item and item[0]['name'] or ''}
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
# ****** Re-cancellculates Basic Rate & amount based on Price List Selected ******
|
||||
def get_adj_percent(self, obj):
|
||||
for d in getlist(obj.doclist, obj.fname):
|
||||
base_ref_rate = self.get_ref_rate(d.item_code, obj.doc.price_list_name, obj.doc.price_list_currency, obj.doc.plc_conversion_rate)
|
||||
d.adj_rate = 0
|
||||
d.ref_rate = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
d.basic_rate = flt(base_ref_rate)
|
||||
d.base_ref_rate = flt(base_ref_rate)
|
||||
d.export_rate = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
d.amount = flt(d.qty)*flt(base_ref_rate)
|
||||
d.export_amount = flt(d.qty)*flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
|
||||
|
||||
# Load Default Taxes
|
||||
# ====================
|
||||
def load_default_taxes(self, obj):
|
||||
if cstr(obj.doc.charge):
|
||||
return self.get_other_charges(obj)
|
||||
else:
|
||||
return self.get_other_charges(obj, 1)
|
||||
|
||||
|
||||
# Get other charges from Master
|
||||
# =================================================================================
|
||||
def get_other_charges(self,obj, default=0):
|
||||
obj.doclist = obj.doc.clear_table(obj.doclist, 'other_charges')
|
||||
if not getlist(obj.doclist, 'other_charges'):
|
||||
if default: add_cond = 'ifnull(t2.is_default,0) = 1'
|
||||
else: add_cond = 't1.parent = "'+cstr(obj.doc.charge)+'"'
|
||||
idx = 0
|
||||
other_charge = webnotes.conn.sql("""\
|
||||
select t1.*
|
||||
from
|
||||
`tabSales Taxes and Charges` t1,
|
||||
`tabSales Taxes and Charges Master` t2
|
||||
where
|
||||
t1.parent = t2.name and
|
||||
t2.company = '%s' and
|
||||
%s
|
||||
order by t1.idx""" % (obj.doc.company, add_cond), as_dict=1)
|
||||
from webnotes.model import default_fields
|
||||
for other in other_charge:
|
||||
# remove default fields like parent, parenttype etc.
|
||||
# from query results
|
||||
for field in default_fields:
|
||||
if field in other: del other[field]
|
||||
|
||||
d = addchild(obj.doc, 'other_charges', 'Sales Taxes and Charges', 1,
|
||||
obj.doclist)
|
||||
d.fields.update(other)
|
||||
d.rate = flt(d.rate)
|
||||
d.tax_amount = flt(d.tax_rate)
|
||||
d.included_in_print_rate = cint(d.included_in_print_rate)
|
||||
d.idx = idx
|
||||
idx += 1
|
||||
return obj.doclist
|
||||
|
||||
# Get TERMS AND CONDITIONS
|
||||
# =======================================================================================
|
||||
def get_tc_details(self,obj):
|
||||
r = webnotes.conn.sql("select terms from `tabTerms and Conditions` where name = %s", obj.doc.tc_name)
|
||||
if r: obj.doc.terms = r[0][0]
|
||||
|
||||
#---------------------------------------- Get Tax Details -------------------------------#
|
||||
def get_tax_details(self, item_code, obj):
|
||||
import json
|
||||
tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , item_code)
|
||||
t = {}
|
||||
for x in tax: t[x[0]] = flt(x[1])
|
||||
ret = {
|
||||
'item_tax_rate' : tax and json.dumps(t) or ''
|
||||
}
|
||||
return ret
|
||||
|
||||
# Get Serial No Details
|
||||
# ==========================================================================
|
||||
def get_serial_details(self, serial_no, obj):
|
||||
import json
|
||||
item = webnotes.conn.sql("select item_code, make, label,brand, description from `tabSerial No` where name = '%s' and docstatus != 2" %(serial_no), as_dict=1)
|
||||
tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , item[0]['item_code'])
|
||||
t = {}
|
||||
for x in tax: t[x[0]] = flt(x[1])
|
||||
ret = {
|
||||
'item_code' : item and item[0]['item_code'] or '',
|
||||
'make' : item and item[0]['make'] or '',
|
||||
'label' : item and item[0]['label'] or '',
|
||||
'brand' : item and item[0]['brand'] or '',
|
||||
'description' : item and item[0]['description'] or '',
|
||||
'item_tax_rate' : json.dumps(t)
|
||||
}
|
||||
return ret
|
||||
|
||||
# Get Commission rate
|
||||
# =======================================================================
|
||||
def get_comm_rate(self, sales_partner, obj):
|
||||
|
||||
comm_rate = webnotes.conn.sql("select commission_rate from `tabSales Partner` where name = '%s' and docstatus != 2" %(sales_partner), as_dict=1)
|
||||
if comm_rate:
|
||||
total_comm = flt(comm_rate[0]['commission_rate']) * flt(obj.doc.net_total) / 100
|
||||
ret = {
|
||||
'commission_rate' : comm_rate and flt(comm_rate[0]['commission_rate']) or 0,
|
||||
'total_commission' : flt(total_comm)
|
||||
}
|
||||
return ret
|
||||
else:
|
||||
msgprint("Business Associate : %s does not exist in the system." % (sales_partner))
|
||||
raise Exception
|
||||
|
||||
|
||||
# To verify whether rate entered in details table does not exceed max discount %
|
||||
# =======================================================================================
|
||||
def validate_max_discount(self,obj, detail_table):
|
||||
for d in getlist(obj.doclist, detail_table):
|
||||
discount = webnotes.conn.sql("select max_discount from tabItem where name = '%s'" %(d.item_code),as_dict = 1)
|
||||
if discount and discount[0]['max_discount'] and (flt(d.adj_rate)>flt(discount[0]['max_discount'])):
|
||||
msgprint("You cannot give more than " + cstr(discount[0]['max_discount']) + " % discount on Item Code : "+cstr(d.item_code))
|
||||
raise Exception
|
||||
|
||||
|
||||
# Get sum of allocated % of sales person (it should be 100%)
|
||||
# ========================================================================
|
||||
# it indicates % contribution of sales person in sales
|
||||
def get_allocated_sum(self,obj):
|
||||
sum = 0
|
||||
for d in getlist(obj.doclist,'sales_team'):
|
||||
sum += flt(d.allocated_percentage)
|
||||
if (flt(sum) != 100) and getlist(obj.doclist,'sales_team'):
|
||||
msgprint("Total Allocated % of Sales Persons should be 100%")
|
||||
raise Exception
|
||||
|
||||
# Check Conversion Rate (i.e. it will not allow conversion rate to be 1 for Currency other than default currency set in Global Defaults)
|
||||
# ===========================================================================
|
||||
def check_conversion_rate(self, obj):
|
||||
default_currency = TransactionBase().get_company_currency(obj.doc.company)
|
||||
if not default_currency:
|
||||
msgprint('Message: Please enter default currency in Company Master')
|
||||
raise Exception
|
||||
if (obj.doc.currency == default_currency and flt(obj.doc.conversion_rate) != 1.00) or not obj.doc.conversion_rate or (obj.doc.currency != default_currency and flt(obj.doc.conversion_rate) == 1.00):
|
||||
msgprint("Please Enter Appropriate Conversion Rate for Customer's Currency to Base Currency (%s --> %s)" % (obj.doc.currency, default_currency), raise_exception = 1)
|
||||
|
||||
if (obj.doc.price_list_currency == default_currency and flt(obj.doc.plc_conversion_rate) != 1.00) or not obj.doc.plc_conversion_rate or (obj.doc.price_list_currency != default_currency and flt(obj.doc.plc_conversion_rate) == 1.00):
|
||||
msgprint("Please Enter Appropriate Conversion Rate for Price List Currency to Base Currency ( (%s --> %s)" % (obj.doc.price_list_currency, default_currency), raise_exception = 1)
|
||||
|
||||
|
||||
|
||||
# Get Tax rate if account type is TAX
|
||||
# =========================================================================
|
||||
def get_rate(self, arg):
|
||||
arg = eval(arg)
|
||||
rate = webnotes.conn.sql("select account_type, tax_rate from `tabAccount` where name = '%s' and docstatus != 2" %(arg['account_head']), as_dict=1)
|
||||
ret = {'rate' : 0}
|
||||
if arg['charge_type'] == 'Actual' and rate[0]['account_type'] == 'Tax':
|
||||
msgprint("You cannot select ACCOUNT HEAD of type TAX as your CHARGE TYPE is 'ACTUAL'")
|
||||
ret = {
|
||||
'account_head' : ''
|
||||
}
|
||||
elif rate[0]['account_type'] in ['Tax', 'Chargeable'] and not arg['charge_type'] == 'Actual':
|
||||
ret = {
|
||||
'rate' : rate and flt(rate[0]['tax_rate']) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
def get_item_list(self, obj, is_stopped=0):
|
||||
"""get item list"""
|
||||
il = []
|
||||
for d in getlist(obj.doclist,obj.fname):
|
||||
reserved_wh, reserved_qty = '', 0 # used for delivery note
|
||||
qty = flt(d.qty)
|
||||
if is_stopped:
|
||||
qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0
|
||||
|
||||
if d.prevdoc_doctype == 'Sales Order':
|
||||
# used in delivery note to reduce reserved_qty
|
||||
# Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
|
||||
# But in this case reserved qty should only be reduced by 10 and not 12.
|
||||
|
||||
tot_qty, max_qty, tot_amt, max_amt, reserved_wh = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, obj.doc.name, obj.doc.doctype)
|
||||
if((flt(tot_qty) + flt(qty) > flt(max_qty))):
|
||||
reserved_qty = -(flt(max_qty)-flt(tot_qty))
|
||||
else:
|
||||
reserved_qty = - flt(qty)
|
||||
|
||||
if obj.doc.doctype == 'Sales Order':
|
||||
reserved_wh = d.reserved_warehouse
|
||||
|
||||
if self.has_sales_bom(d.item_code):
|
||||
for p in getlist(obj.doclist, 'packing_details'):
|
||||
if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
|
||||
# the packing details table's qty is already multiplied with parent's qty
|
||||
il.append({
|
||||
'warehouse': p.warehouse,
|
||||
'reserved_warehouse': reserved_wh,
|
||||
'item_code': p.item_code,
|
||||
'qty': flt(p.qty),
|
||||
'reserved_qty': (flt(p.qty)/qty)*(reserved_qty),
|
||||
'uom': p.uom,
|
||||
'batch_no': p.batch_no,
|
||||
'serial_no': p.serial_no,
|
||||
'name': d.name
|
||||
})
|
||||
else:
|
||||
il.append({
|
||||
'warehouse': d.warehouse,
|
||||
'reserved_warehouse': reserved_wh,
|
||||
'item_code': d.item_code,
|
||||
'qty': qty,
|
||||
'reserved_qty': reserved_qty,
|
||||
'uom': d.stock_uom,
|
||||
'batch_no': d.batch_no,
|
||||
'serial_no': d.serial_no,
|
||||
'name': d.name
|
||||
})
|
||||
return il
|
||||
|
||||
|
||||
def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name, curr_parent_doctype):
|
||||
""" Get qty, amount already billed or delivered against curr line item for current doctype
|
||||
For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV
|
||||
"""
|
||||
#Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction
|
||||
if curr_parent_doctype == 'Installation Note':
|
||||
curr_det = webnotes.conn.sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
|
||||
qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0
|
||||
else:
|
||||
curr_det = webnotes.conn.sql("select sum(qty), sum(amount) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
|
||||
qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0
|
||||
|
||||
# get total qty of ref doctype
|
||||
so_det = webnotes.conn.sql("select qty, amount, reserved_warehouse from `tabSales Order Item` where name = '%s' and docstatus = 1"% ref_tab_dn)
|
||||
max_qty, max_amt, res_wh = so_det and flt(so_det[0][0]) or 0, so_det and flt(so_det[0][1]) or 0, so_det and cstr(so_det[0][2]) or ''
|
||||
return qty, max_qty, amt, max_amt, res_wh
|
||||
|
||||
|
||||
# Make Packing List from Sales BOM
|
||||
# =======================================================================
|
||||
def has_sales_bom(self, item_code):
|
||||
return webnotes.conn.sql("select name from `tabSales BOM` where new_item_code=%s and docstatus != 2", item_code)
|
||||
|
||||
def get_sales_bom_items(self, item_code):
|
||||
return webnotes.conn.sql("""select t1.item_code, t1.qty, t1.uom
|
||||
from `tabSales BOM Item` t1, `tabSales BOM` t2
|
||||
where t2.new_item_code=%s and t1.parent = t2.name""", item_code, as_dict=1)
|
||||
|
||||
def get_packing_item_details(self, item):
|
||||
return webnotes.conn.sql("select item_name, description, stock_uom from `tabItem` where name = %s", item, as_dict = 1)[0]
|
||||
|
||||
def get_bin_qty(self, item, warehouse):
|
||||
det = webnotes.conn.sql("select actual_qty, projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (item, warehouse), as_dict = 1)
|
||||
return det and det[0] or ''
|
||||
|
||||
def update_packing_list_item(self,obj, packing_item_code, qty, warehouse, line):
|
||||
bin = self.get_bin_qty(packing_item_code, warehouse)
|
||||
item = self.get_packing_item_details(packing_item_code)
|
||||
|
||||
# check if exists
|
||||
exists = 0
|
||||
for d in getlist(obj.doclist, 'packing_details'):
|
||||
if d.parent_item == line.item_code and d.item_code == packing_item_code and d.parent_detail_docname == line.name:
|
||||
pi, exists = d, 1
|
||||
break
|
||||
|
||||
if not exists:
|
||||
pi = addchild(obj.doc, 'packing_details', 'Delivery Note Packing Item', 1, obj.doclist)
|
||||
|
||||
pi.parent_item = line.item_code
|
||||
pi.item_code = packing_item_code
|
||||
pi.item_name = item['item_name']
|
||||
pi.parent_detail_docname = line.name
|
||||
pi.description = item['description']
|
||||
pi.uom = item['stock_uom']
|
||||
pi.qty = flt(qty)
|
||||
pi.actual_qty = bin and flt(bin['actual_qty']) or 0
|
||||
pi.projected_qty = bin and flt(bin['projected_qty']) or 0
|
||||
pi.prevdoc_doctype = line.prevdoc_doctype
|
||||
if not pi.warehouse:
|
||||
pi.warehouse = warehouse
|
||||
if not pi.batch_no:
|
||||
pi.batch_no = cstr(line.batch_no)
|
||||
pi.idx = self.packing_list_idx
|
||||
|
||||
# saved, since this function is called on_update of delivery note
|
||||
pi.save()
|
||||
|
||||
self.packing_list_idx += 1
|
||||
|
||||
|
||||
def make_packing_list(self, obj, fname):
|
||||
"""make packing list for sales bom item"""
|
||||
self.packing_list_idx = 0
|
||||
parent_items = []
|
||||
for d in getlist(obj.doclist, fname):
|
||||
warehouse = fname == "sales_order_details" and d.reserved_warehouse or d.warehouse
|
||||
if self.has_sales_bom(d.item_code):
|
||||
for i in self.get_sales_bom_items(d.item_code):
|
||||
self.update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), warehouse, d)
|
||||
|
||||
if [d.item_code, d.name] not in parent_items:
|
||||
parent_items.append([d.item_code, d.name])
|
||||
|
||||
obj.doclist = self.cleanup_packing_list(obj, parent_items)
|
||||
|
||||
return obj.doclist
|
||||
|
||||
def cleanup_packing_list(self, obj, parent_items):
|
||||
"""Remove all those child items which are no longer present in main item table"""
|
||||
delete_list = []
|
||||
for d in getlist(obj.doclist, 'packing_details'):
|
||||
if [d.parent_item, d.parent_detail_docname] not in parent_items:
|
||||
# mark for deletion from doclist
|
||||
delete_list.append(d.name)
|
||||
|
||||
if not delete_list:
|
||||
return obj.doclist
|
||||
|
||||
# delete from doclist
|
||||
obj.doclist = filter(lambda d: d.name not in delete_list, obj.doclist)
|
||||
|
||||
# delete from db
|
||||
webnotes.conn.sql("""\
|
||||
delete from `tabDelivery Note Packing Item`
|
||||
where name in (%s)"""
|
||||
% (", ".join(["%s"] * len(delete_list))),
|
||||
tuple(delete_list))
|
||||
|
||||
return obj.doclist
|
||||
|
||||
# Get total in words
|
||||
# ==================================================================
|
||||
def get_total_in_words(self, currency, amount):
|
||||
from webnotes.utils import money_in_words
|
||||
return money_in_words(amount, currency)
|
||||
|
||||
|
||||
# Get month based on date (required in sales person and sales partner)
|
||||
# ========================================================================
|
||||
def get_month(self,date):
|
||||
month_list = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
month_idx = cint(cstr(date).split('-')[1])-1
|
||||
return month_list[month_idx]
|
||||
|
||||
|
||||
# **** Check for Stop SO as no transactions can be made against Stopped SO. Need to unstop it. ***
|
||||
def check_stop_sales_order(self,obj):
|
||||
for d in getlist(obj.doclist,obj.fname):
|
||||
ref_doc_name = ''
|
||||
if d.fields.has_key('prevdoc_docname') and d.prevdoc_docname and d.prevdoc_doctype == 'Sales Order':
|
||||
ref_doc_name = d.prevdoc_docname
|
||||
elif d.fields.has_key('sales_order') and d.sales_order and not d.delivery_note:
|
||||
ref_doc_name = d.sales_order
|
||||
if ref_doc_name:
|
||||
so_status = webnotes.conn.sql("select status from `tabSales Order` where name = %s",ref_doc_name)
|
||||
so_status = so_status and so_status[0][0] or ''
|
||||
if so_status == 'Stopped':
|
||||
msgprint("You cannot do any transaction against Sales Order : '%s' as it is Stopped." %(ref_doc_name))
|
||||
raise Exception
|
||||
|
||||
|
||||
# ****** Check for Item.is_sales_item = 'Yes' and Item.docstatus != 2 *******
|
||||
def check_active_sales_items(self,obj):
|
||||
for d in getlist(obj.doclist, obj.fname):
|
||||
if d.item_code: # extra condn coz item_code is not mandatory in RV
|
||||
valid_item = webnotes.conn.sql("select docstatus,is_sales_item, is_service_item from tabItem where name = %s",d.item_code)
|
||||
if valid_item and valid_item[0][0] == 2:
|
||||
msgprint("Item : '%s' does not exist in system." %(d.item_code))
|
||||
raise Exception
|
||||
sales_item = valid_item and valid_item[0][1] or 'No'
|
||||
service_item = valid_item and valid_item[0][2] or 'No'
|
||||
if sales_item == 'No' and service_item == 'No':
|
||||
msgprint("Item : '%s' is neither Sales nor Service Item"%(d.item_code))
|
||||
raise Exception
|
||||
|
||||
|
||||
# **************************************************************************************************************************************************
|
||||
|
||||
def check_credit(self,obj,grand_total):
|
||||
acc_head = webnotes.conn.sql("select name from `tabAccount` where company = '%s' and master_name = '%s'"%(obj.doc.company, obj.doc.customer))
|
||||
if acc_head:
|
||||
tot_outstanding = 0
|
||||
dbcr = webnotes.conn.sql("select sum(debit), sum(credit) from `tabGL Entry` where account = '%s' and ifnull(is_cancelled, 'No')='No'" % acc_head[0][0])
|
||||
if dbcr:
|
||||
tot_outstanding = flt(dbcr[0][0])-flt(dbcr[0][1])
|
||||
|
||||
exact_outstanding = flt(tot_outstanding) + flt(grand_total)
|
||||
get_obj('Account',acc_head[0][0]).check_credit_limit(acc_head[0][0], obj.doc.company, exact_outstanding)
|
||||
|
||||
def validate_fiscal_year(self,fiscal_year,transaction_date,dn):
|
||||
fy=webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name='%s'"%fiscal_year)
|
||||
ysd=fy and fy[0][0] or ""
|
||||
yed=add_days(str(ysd),365)
|
||||
if str(transaction_date) < str(ysd) or str(transaction_date) > str(yed):
|
||||
msgprint("%s not within the fiscal year"%(dn))
|
||||
raise Exception
|
||||
|
||||
|
||||
# get against document date self.prevdoc_date_field
|
||||
#-----------------------------
|
||||
def get_prevdoc_date(self, obj):
|
||||
import datetime
|
||||
for d in getlist(obj.doclist, obj.fname):
|
||||
if d.prevdoc_doctype and d.prevdoc_docname:
|
||||
if d.prevdoc_doctype == 'Sales Invoice':
|
||||
dt = webnotes.conn.sql("select posting_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname))
|
||||
else:
|
||||
dt = webnotes.conn.sql("select transaction_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname))
|
||||
d.prevdoc_date = (dt and dt[0][0]) and dt[0][0].strftime('%Y-%m-%d') or ''
|
||||
|
||||
def update_prevdoc_detail(self, is_submit, obj):
|
||||
StatusUpdater(obj, is_submit).update()
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# make item code readonly if (detail no is set)
|
||||
#
|
||||
|
||||
|
||||
class StatusUpdater:
|
||||
"""
|
||||
Updates the status of the calling records
|
||||
|
||||
From Delivery Note
|
||||
- Update Delivered Qty
|
||||
- Update Percent
|
||||
- Validate over delivery
|
||||
|
||||
From Sales Invoice
|
||||
- Update Billed Amt
|
||||
- Update Percent
|
||||
- Validate over billing
|
||||
|
||||
From Installation Note
|
||||
- Update Installed Qty
|
||||
- Update Percent Qty
|
||||
- Validate over installation
|
||||
"""
|
||||
def __init__(self, obj, is_submit):
|
||||
self.obj = obj # caller object
|
||||
self.is_submit = is_submit
|
||||
self.tolerance = {}
|
||||
self.global_tolerance = None
|
||||
|
||||
def update(self):
|
||||
self.update_all_qty()
|
||||
self.validate_all_qty()
|
||||
|
||||
def validate_all_qty(self):
|
||||
"""
|
||||
Validates over-billing / delivery / installation in Delivery Note, Sales Invoice, Installation Note
|
||||
To called after update_all_qty
|
||||
"""
|
||||
if self.obj.doc.doctype=='Delivery Note':
|
||||
self.validate_qty({
|
||||
'source_dt' :'Delivery Note Item',
|
||||
'compare_field' :'delivered_qty',
|
||||
'compare_ref_field' :'qty',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'join_field' :'prevdoc_detail_docname'
|
||||
})
|
||||
elif self.obj.doc.doctype=='Sales Invoice':
|
||||
self.validate_qty({
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'compare_field' :'billed_amt',
|
||||
'compare_ref_field' :'export_amount',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'join_field' :'so_detail'
|
||||
})
|
||||
self.validate_qty({
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'compare_field' :'billed_amt',
|
||||
'compare_ref_field' :'export_amount',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'join_field' :'dn_detail'
|
||||
}, no_tolerance =1)
|
||||
elif self.obj.doc.doctype=='Installation Note':
|
||||
self.validate_qty({
|
||||
'source_dt' :'Installation Item Details',
|
||||
'compare_field' :'installed_qty',
|
||||
'compare_ref_field' :'qty',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'join_field' :'dn_detail'
|
||||
}, no_tolerance =1)
|
||||
|
||||
|
||||
def get_tolerance_for(self, item_code):
|
||||
"""
|
||||
Returns the tolerance for the item, if not set, returns global tolerance
|
||||
"""
|
||||
if self.tolerance.get(item_code):
|
||||
return self.tolerance[item_code]
|
||||
|
||||
tolerance = flt(get_value('Item',item_code,'tolerance') or 0)
|
||||
|
||||
if not(tolerance):
|
||||
if self.global_tolerance == None:
|
||||
self.global_tolerance = flt(get_value('Global Defaults',None,'tolerance') or 0)
|
||||
tolerance = self.global_tolerance
|
||||
|
||||
self.tolerance[item_code] = tolerance
|
||||
return tolerance
|
||||
|
||||
def check_overflow_with_tolerance(self, item, args):
|
||||
"""
|
||||
Checks if there is overflow condering a relaxation tolerance
|
||||
"""
|
||||
|
||||
# check if overflow is within tolerance
|
||||
tolerance = self.get_tolerance_for(item['item_code'])
|
||||
overflow_percent = ((item[args['compare_field']] - item[args['compare_ref_field']]) / item[args['compare_ref_field']] * 100)
|
||||
|
||||
if overflow_percent - tolerance > 0.01:
|
||||
item['max_allowed'] = flt(item[args['compare_ref_field']] * (100+tolerance)/100)
|
||||
item['reduce_by'] = item[args['compare_field']] - item['max_allowed']
|
||||
|
||||
msgprint("""
|
||||
Row #%(idx)s: Max %(compare_ref_field)s allowed for <b>Item %(item_code)s</b> against <b>%(parenttype)s %(parent)s</b> is <b>%(max_allowed)s</b>.
|
||||
|
||||
If you want to increase your overflow tolerance, please increase tolerance %% in Global Defaults or Item master.
|
||||
|
||||
Or, you must reduce the %(compare_ref_field)s by %(reduce_by)s
|
||||
|
||||
Also, please check if the order item has already been billed in the Sales Order""" % item, raise_exception=1)
|
||||
|
||||
def validate_qty(self, args, no_tolerance=None):
|
||||
"""
|
||||
Validates qty at row level
|
||||
"""
|
||||
# get unique transactions to update
|
||||
for d in self.obj.doclist:
|
||||
if d.doctype == args['source_dt']:
|
||||
args['name'] = d.fields[args['join_field']]
|
||||
|
||||
# get all qty where qty > compare_field
|
||||
item = webnotes.conn.sql("""
|
||||
select item_code, `%(compare_ref_field)s`, `%(compare_field)s`, parenttype, parent from `tab%(target_dt)s`
|
||||
where `%(compare_ref_field)s` < `%(compare_field)s` and name="%(name)s" and docstatus=1
|
||||
""" % args, as_dict=1)
|
||||
if item:
|
||||
item = item[0]
|
||||
item['idx'] = d.idx
|
||||
item['compare_ref_field'] = args['compare_ref_field'].replace('_', ' ')
|
||||
|
||||
if not item[args['compare_ref_field']]:
|
||||
msgprint("As %(compare_ref_field)s for item: %(item_code)s in %(parenttype)s: %(parent)s is zero, system will not check over-delivery or over-billed" % item)
|
||||
elif no_tolerance:
|
||||
item['reduce_by'] = item[args['compare_field']] - item[args['compare_ref_field']]
|
||||
if item['reduce_by'] > .01:
|
||||
msgprint("""
|
||||
Row #%(idx)s: Max %(compare_ref_field)s allowed for <b>Item %(item_code)s</b> against
|
||||
<b>%(parenttype)s %(parent)s</b> is <b>""" % item
|
||||
+ cstr(item[args['compare_ref_field']]) + """</b>.
|
||||
|
||||
You must reduce the %(compare_ref_field)s by %(reduce_by)s""" % item, raise_exception=1)
|
||||
|
||||
else:
|
||||
self.check_overflow_with_tolerance(item, args)
|
||||
|
||||
|
||||
def update_all_qty(self):
|
||||
"""
|
||||
Updates delivered / billed / installed qty in Sales Order & Delivery Note
|
||||
"""
|
||||
if self.obj.doc.doctype=='Delivery Note':
|
||||
self.update_qty({
|
||||
'target_field' :'delivered_qty',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'target_parent_dt' :'Sales Order',
|
||||
'target_parent_field' :'per_delivered',
|
||||
'target_ref_field' :'qty',
|
||||
'source_dt' :'Delivery Note Item',
|
||||
'source_field' :'qty',
|
||||
'join_field' :'prevdoc_detail_docname',
|
||||
'percent_join_field' :'prevdoc_docname',
|
||||
'status_field' :'delivery_status',
|
||||
'keyword' :'Delivered'
|
||||
})
|
||||
|
||||
elif self.obj.doc.doctype=='Sales Invoice':
|
||||
self.update_qty({
|
||||
'target_field' :'billed_amt',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'target_parent_dt' :'Sales Order',
|
||||
'target_parent_field' :'per_billed',
|
||||
'target_ref_field' :'export_amount',
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'source_field' :'export_amount',
|
||||
'join_field' :'so_detail',
|
||||
'percent_join_field' :'sales_order',
|
||||
'status_field' :'billing_status',
|
||||
'keyword' :'Billed'
|
||||
})
|
||||
|
||||
self.update_qty({
|
||||
'target_field' :'billed_amt',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'target_parent_dt' :'Delivery Note',
|
||||
'target_parent_field' :'per_billed',
|
||||
'target_ref_field' :'export_amount',
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'source_field' :'export_amount',
|
||||
'join_field' :'dn_detail',
|
||||
'percent_join_field' :'delivery_note',
|
||||
'status_field' :'billing_status',
|
||||
'keyword' :'Billed'
|
||||
})
|
||||
|
||||
if self.obj.doc.doctype=='Installation Note':
|
||||
self.update_qty({
|
||||
'target_field' :'installed_qty',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'target_parent_dt' :'Delivery Note',
|
||||
'target_parent_field' :'per_installed',
|
||||
'target_ref_field' :'qty',
|
||||
'source_dt' :'Installation Note Item',
|
||||
'source_field' :'qty',
|
||||
'join_field' :'prevdoc_detail_docname',
|
||||
'percent_join_field' :'prevdoc_docname',
|
||||
'status_field' :'installation_status',
|
||||
'keyword' :'Installed'
|
||||
})
|
||||
|
||||
|
||||
def update_qty(self, args):
|
||||
"""
|
||||
Updates qty at row level
|
||||
"""
|
||||
# condition to include current record (if submit or no if cancel)
|
||||
if self.is_submit:
|
||||
args['cond'] = ' or parent="%s"' % self.obj.doc.name
|
||||
else:
|
||||
args['cond'] = ' and parent!="%s"' % self.obj.doc.name
|
||||
|
||||
# update quantities in child table
|
||||
for d in self.obj.doclist:
|
||||
if d.doctype == args['source_dt']:
|
||||
# updates qty in the child table
|
||||
args['detail_id'] = d.fields.get(args['join_field'])
|
||||
|
||||
if args['detail_id']:
|
||||
webnotes.conn.sql("""
|
||||
update
|
||||
`tab%(target_dt)s`
|
||||
set
|
||||
%(target_field)s = (select sum(%(source_field)s) from `tab%(source_dt)s` where `%(join_field)s`="%(detail_id)s" and (docstatus=1 %(cond)s))
|
||||
where
|
||||
name="%(detail_id)s"
|
||||
""" % args)
|
||||
|
||||
# get unique transactions to update
|
||||
for name in set([d.fields.get(args['percent_join_field']) for d in self.obj.doclist if d.doctype == args['source_dt']]):
|
||||
if name:
|
||||
args['name'] = name
|
||||
|
||||
# update percent complete in the parent table
|
||||
webnotes.conn.sql("""
|
||||
update
|
||||
`tab%(target_parent_dt)s`
|
||||
set
|
||||
%(target_parent_field)s =
|
||||
(select sum(if(%(target_ref_field)s > ifnull(%(target_field)s, 0), %(target_field)s, %(target_ref_field)s))/sum(%(target_ref_field)s)*100 from `tab%(target_dt)s` where parent="%(name)s"),
|
||||
modified = now()
|
||||
where
|
||||
name="%(name)s"
|
||||
""" % args)
|
||||
|
||||
# update field
|
||||
if args['status_field']:
|
||||
webnotes.conn.sql("""
|
||||
update
|
||||
`tab%(target_parent_dt)s`
|
||||
set
|
||||
%(status_field)s = if(ifnull(%(target_parent_field)s,0)<0.001, 'Not %(keyword)s',
|
||||
if(%(target_parent_field)s>=99.99, 'Fully %(keyword)s', 'Partly %(keyword)s')
|
||||
)
|
||||
where
|
||||
name="%(name)s"
|
||||
""" % args)
|
||||
|
||||
31
selling/doctype/sales_common/sales_common.txt
Normal file
31
selling/doctype/sales_common/sales_common.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# DocType, Sales Common
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:14',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:14',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'issingle': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 290
|
||||
},
|
||||
|
||||
# DocType, Sales Common
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales Common'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sales_order/__init__.py
Normal file
1
selling/doctype/sales_order/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
365
selling/doctype/sales_order/sales_order.js
Normal file
365
selling/doctype/sales_order/sales_order.js
Normal file
@@ -0,0 +1,365 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Module CRM
|
||||
|
||||
cur_frm.cscript.tname = "Sales Order Item";
|
||||
cur_frm.cscript.fname = "sales_order_details";
|
||||
cur_frm.cscript.other_fname = "other_charges";
|
||||
cur_frm.cscript.sales_team_fname = "sales_team";
|
||||
|
||||
|
||||
wn.require('erpnext/selling/doctype/sales_common/sales_common.js');
|
||||
wn.require('erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/setup/doctype/notification_control/notification_control.js');
|
||||
|
||||
|
||||
// ONLOAD
|
||||
// ================================================================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'});
|
||||
if(!doc.transaction_date) set_multiple(cdt,cdn,{transaction_date:get_today()});
|
||||
if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
|
||||
// load default charges
|
||||
|
||||
if(doc.__islocal && !doc.customer){
|
||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group','shipping_address']);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
||||
var callback = function(doc, cdt, cdn) {
|
||||
if(doc.__islocal) {
|
||||
// defined in sales_common.js
|
||||
cur_frm.cscript.update_item_details(doc, cdt, cdn);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn, callback);
|
||||
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
cur_frm.clear_custom_buttons();
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
if (!cur_frm.cscript.is_onload) cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn);
|
||||
|
||||
if(doc.customer) $(cur_frm.fields_dict.contact_info.row.wrapper).toggle(true);
|
||||
else $(cur_frm.fields_dict.contact_info.row.wrapper).toggle(false);
|
||||
|
||||
if(doc.docstatus==1) {
|
||||
if(doc.status != 'Stopped') {
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
// delivery note
|
||||
if(doc.per_delivered < 100 && doc.order_type=='Sales')
|
||||
cur_frm.add_custom_button('Make Delivery', cur_frm.cscript['Make Delivery Note']);
|
||||
|
||||
// maintenance
|
||||
if(doc.per_delivered < 100 && (doc.order_type !='Sales')) {
|
||||
cur_frm.add_custom_button('Make Maint. Visit', cur_frm.cscript.make_maintenance_visit);
|
||||
cur_frm.add_custom_button('Make Maint. Schedule', cur_frm.cscript['Make Maintenance Schedule']);
|
||||
}
|
||||
|
||||
// indent
|
||||
if(!doc.order_type || (doc.order_type == 'Sales'))
|
||||
cur_frm.add_custom_button('Make ' + get_doctype_label('Purchase Request'), cur_frm.cscript['Make Purchase Request']);
|
||||
|
||||
// sales invoice
|
||||
if(doc.per_billed < 100)
|
||||
cur_frm.add_custom_button('Make Invoice', cur_frm.cscript['Make Sales Invoice']);
|
||||
|
||||
// stop
|
||||
if(doc.per_delivered < 100 || doc.per_billed < 100)
|
||||
cur_frm.add_custom_button('Stop!', cur_frm.cscript['Stop Sales Order']);
|
||||
} else {
|
||||
// un-stop
|
||||
cur_frm.add_custom_button('Unstop', cur_frm.cscript['Unstop Sales Order']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
var pl = doc.price_list_name;
|
||||
var callback = function(r,rt) {
|
||||
var callback2 = function(r, rt) {
|
||||
|
||||
if(doc.customer) unhide_field(['customer_address', 'contact_person', 'territory','customer_group','shipping_address']);
|
||||
cur_frm.refresh();
|
||||
|
||||
if(!onload && (pl != doc.price_list_name)) cur_frm.cscript.price_list_name(doc, dt, dn);
|
||||
|
||||
}
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
get_server_fields('get_shipping_address',doc.customer,'',doc, dt, dn, 0, callback2);
|
||||
|
||||
}
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.pull_quotation_details = function(doc,dt,dn) {
|
||||
var callback = function(r,rt){
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
if(r.message){
|
||||
doc.quotation_no = r.message;
|
||||
if(doc.quotation_no) {
|
||||
unhide_field(['quotation_date','customer_address','contact_person','territory','customer_group','shipping_address']);
|
||||
if(doc.customer) get_server_fields('get_shipping_address',doc.customer,'',doc, dt, dn, 0);
|
||||
}
|
||||
cur_frm.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_quotation_details','',callback);
|
||||
}
|
||||
|
||||
|
||||
//================ create new contact ============================================================================
|
||||
cur_frm.cscript.new_contact = function(){
|
||||
tn = createLocal('Contact');
|
||||
locals['Contact'][tn].is_customer = 1;
|
||||
if(doc.customer) locals['Contact'][tn].customer = doc.customer;
|
||||
loaddoc('Contact', tn);
|
||||
}
|
||||
|
||||
// DOCTYPE TRIGGERS
|
||||
// ================================================================================================
|
||||
|
||||
|
||||
// ***************** Get project name *****************
|
||||
cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
|
||||
var cond = '';
|
||||
if(doc.customer) cond = '(`tabProject`.customer = "'+doc.customer+'" OR IFNULL(`tabProject`.customer,"")="") AND';
|
||||
return repl('SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.status = "Open" AND %(cond)s `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50', {cond:cond});
|
||||
}
|
||||
|
||||
//---- get customer details ----------------------------
|
||||
cur_frm.cscript.project_name = function(doc,cdt,cdn){
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_project_customer','', function(r,rt){
|
||||
refresh_many(['customer','customer_name', 'customer_address', 'contact_person', 'territory', 'contact_no', 'email_id', 'customer_group']);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *************** Customized link query for QUOTATION *****************************
|
||||
cur_frm.fields_dict['quotation_no'].get_query = function(doc) {
|
||||
var cond='';
|
||||
if(doc.order_type) cond = ' ifnull(`tabQuotation`.order_type, "") = "'+doc.order_type+'" and';
|
||||
if(doc.customer) cond += ' ifnull(`tabQuotation`.customer, "") = "'+doc.customer+'" and';
|
||||
|
||||
return repl('SELECT DISTINCT name, customer, transaction_date FROM `tabQuotation` WHERE `tabQuotation`.company = "' + doc.company + '" and `tabQuotation`.`docstatus` = 1 and `tabQuotation`.status != "Order Lost" and %(cond)s `tabQuotation`.%(key)s LIKE "%s" ORDER BY `tabQuotation`.`name` DESC LIMIT 50', {cond:cond});
|
||||
}
|
||||
|
||||
|
||||
// SALES ORDER DETAILS TRIGGERS
|
||||
// ================================================================================================
|
||||
|
||||
// ***************** Get available qty in warehouse of item selected ****************
|
||||
cur_frm.cscript.reserved_warehouse = function(doc, cdt , cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.reserved_warehouse) {
|
||||
arg = "{'item_code':'" + d.item_code + "','warehouse':'" + d.reserved_warehouse +"'}";
|
||||
get_server_fields('get_available_qty',arg,'sales_order_details',doc,cdt,cdn,1);
|
||||
}
|
||||
}
|
||||
|
||||
//----------- make maintenance schedule----------
|
||||
cur_frm.cscript['Make Maintenance Schedule'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
if (doc.docstatus == 1) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'check_maintenance_schedule','',
|
||||
function(r,rt){
|
||||
if(r.message == 'No'){
|
||||
n = createLocal("Maintenance Schedule");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Maintenance Schedule"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Maintenance Schedule',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Maintenance Schedule'], ['Sales Order Item', 'Maintenance Schedule Item']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Maintenance Schedule", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
else{
|
||||
msgprint("You have already created Maintenance Schedule against this Sales Order");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//------------ make maintenance visit ------------
|
||||
cur_frm.cscript.make_maintenance_visit = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
if (doc.docstatus == 1) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'check_maintenance_visit','',
|
||||
function(r,rt){
|
||||
if(r.message == 'No'){
|
||||
n = createLocal("Maintenance Visit");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Maintenance Visit"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Maintenance Visit',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Maintenance Visit'], ['Sales Order Item', 'Maintenance Visit Purpose']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Maintenance Visit", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
else{
|
||||
msgprint("You have already completed maintenance against this Sales Order");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// make indent
|
||||
// ================================================================================================
|
||||
cur_frm.cscript['Make Purchase Request'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
if (doc.docstatus == 1) {
|
||||
n = createLocal("Purchase Request");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Purchase Request"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Purchase Request',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Purchase Request'], ['Sales Order Item', 'Purchase Request Item']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Purchase Request", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MAKE DELIVERY NOTE
|
||||
// ================================================================================================
|
||||
cur_frm.cscript['Make Delivery Note'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
if (doc.docstatus == 1) {
|
||||
n = createLocal("Delivery Note");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Delivery Note"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Delivery Note',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Delivery Note'], ['Sales Order Item', 'Delivery Note Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Delivery Note", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MAKE SALES INVOICE
|
||||
// ================================================================================================
|
||||
cur_frm.cscript['Make Sales Invoice'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
n = createLocal('Sales Invoice');
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals['Sales Invoice'][n]]),
|
||||
'from_doctype':doc.doctype,
|
||||
'to_doctype':'Sales Invoice',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order','Sales Invoice'],['Sales Order Item','Sales Invoice Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc('Sales Invoice', n);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// STOP SALES ORDER
|
||||
// ==================================================================================================
|
||||
cur_frm.cscript['Stop Sales Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
var check = confirm("Are you sure you want to STOP " + doc.name);
|
||||
|
||||
if (check) {
|
||||
$c('runserverobj', args={'method':'stop_sales_order', 'docs': compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt) {
|
||||
cur_frm.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// UNSTOP SALES ORDER
|
||||
// ==================================================================================================
|
||||
cur_frm.cscript['Unstop Sales Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
var check = confirm("Are you sure you want to UNSTOP " + doc.name);
|
||||
|
||||
if (check) {
|
||||
$c('runserverobj', args={'method':'unstop_sales_order', 'docs': compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt) {
|
||||
cur_frm.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
//=======================================================================================================================
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
||||
var args = {
|
||||
type: 'Sales Order',
|
||||
doctype: 'Sales Order'
|
||||
}
|
||||
cur_frm.cscript.notify(doc, args);
|
||||
}
|
||||
479
selling/doctype/sales_order/sales_order.py
Normal file
479
selling/doctype/sales_order/sales_order.py
Normal file
@@ -0,0 +1,479 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self, doc, doclist=None):
|
||||
self.doc = doc
|
||||
if not doclist: doclist = []
|
||||
self.doclist = doclist
|
||||
self.tname = 'Sales Order Item'
|
||||
self.fname = 'sales_order_details'
|
||||
self.person_tname = 'Target Detail'
|
||||
self.partner_tname = 'Partner Target Detail'
|
||||
self.territory_tname = 'Territory Target Detail'
|
||||
|
||||
# Autoname
|
||||
# ===============
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# DOCTYPE TRIGGER FUNCTIONS
|
||||
# =============================
|
||||
# Pull Quotation Items
|
||||
# -----------------------
|
||||
def pull_quotation_details(self):
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'other_charges')
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'sales_order_details')
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'sales_team')
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'tc_details')
|
||||
if self.doc.quotation_no:
|
||||
get_obj('DocType Mapper', 'Quotation-Sales Order').dt_map('Quotation', 'Sales Order', self.doc.quotation_no, self.doc, self.doclist, "[['Quotation', 'Sales Order'],['Quotation Item', 'Sales Order Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team'],['TC Detail','TC Detail']]")
|
||||
else:
|
||||
msgprint("Please select Quotation whose details need to pull")
|
||||
|
||||
return cstr(self.doc.quotation_no)
|
||||
|
||||
#pull project customer
|
||||
#-------------------------
|
||||
def pull_project_customer(self):
|
||||
res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
|
||||
if res:
|
||||
get_obj('DocType Mapper', 'Project-Sales Order').dt_map('Project', 'Sales Order', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Order']]")
|
||||
|
||||
|
||||
# Get contact person details based on customer selected
|
||||
# ------------------------------------------------------
|
||||
def get_contact_details(self):
|
||||
get_obj('Sales Common').get_contact_details(self,0)
|
||||
|
||||
# Get Commission rate of Sales Partner
|
||||
# -------------------------------------
|
||||
def get_comm_rate(self, sales_partner):
|
||||
return get_obj('Sales Common').get_comm_rate(sales_partner, self)
|
||||
|
||||
|
||||
# SALES ORDER DETAILS TRIGGER FUNCTIONS
|
||||
# ================================================================================
|
||||
# Get Item Details
|
||||
# ----------------
|
||||
def get_item_details(self, args=None):
|
||||
import json
|
||||
args = args and json.loads(args) or {}
|
||||
if args.get('item_code'):
|
||||
return get_obj('Sales Common').get_item_details(args, self)
|
||||
else:
|
||||
obj = get_obj('Sales Common')
|
||||
for doc in self.doclist:
|
||||
if doc.fields.get('item_code'):
|
||||
arg = {'item_code':doc.fields.get('item_code'), 'income_account':doc.fields.get('income_account'),
|
||||
'cost_center': doc.fields.get('cost_center'), 'warehouse': doc.fields.get('warehouse')};
|
||||
ret = obj.get_item_defaults(arg)
|
||||
for r in ret:
|
||||
if not doc.fields.get(r):
|
||||
doc.fields[r] = ret[r]
|
||||
|
||||
|
||||
# Re-calculates Basic Rate & amount based on Price List Selected
|
||||
# --------------------------------------------------------------
|
||||
def get_adj_percent(self, arg=''):
|
||||
get_obj('Sales Common').get_adj_percent(self)
|
||||
|
||||
|
||||
|
||||
# Get projected qty of item based on warehouse selected
|
||||
# -----------------------------------------------------
|
||||
def get_available_qty(self,args):
|
||||
return get_obj('Sales Common').get_available_qty(eval(args))
|
||||
|
||||
# OTHER CHARGES TRIGGER FUNCTIONS
|
||||
# ====================================================================================
|
||||
|
||||
# Get Tax rate if account type is TAX
|
||||
# ------------------------------------
|
||||
def get_rate(self,arg):
|
||||
return get_obj('Sales Common').get_rate(arg)
|
||||
|
||||
# Load Default Charges
|
||||
# ----------------------------------------------------------
|
||||
def load_default_taxes(self):
|
||||
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
||||
|
||||
# Pull details from other charges master (Get Sales Taxes and Charges Master)
|
||||
# ----------------------------------------------------------
|
||||
def get_other_charges(self):
|
||||
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
||||
|
||||
|
||||
# GET TERMS & CONDITIONS
|
||||
# =====================================================================================
|
||||
def get_tc_details(self):
|
||||
return get_obj('Sales Common').get_tc_details(self)
|
||||
|
||||
#check if maintenance schedule already generated
|
||||
#============================================
|
||||
def check_maintenance_schedule(self):
|
||||
nm = sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", self.doc.name)
|
||||
nm = nm and nm[0][0] or ''
|
||||
|
||||
if not nm:
|
||||
return 'No'
|
||||
|
||||
#check if maintenance visit already generated
|
||||
#============================================
|
||||
def check_maintenance_visit(self):
|
||||
nm = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1 and t1.completion_status='Fully Completed'", self.doc.name)
|
||||
nm = nm and nm[0][0] or ''
|
||||
|
||||
if not nm:
|
||||
return 'No'
|
||||
|
||||
# VALIDATE
|
||||
# =====================================================================================
|
||||
# Fiscal Year Validation
|
||||
# ----------------------
|
||||
def validate_fiscal_year(self):
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Sales Order Date')
|
||||
|
||||
# Validate values with reference document
|
||||
#----------------------------------------
|
||||
def validate_reference_value(self):
|
||||
get_obj('DocType Mapper', 'Quotation-Sales Order', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||
|
||||
# Validate Mandatory
|
||||
# -------------------
|
||||
def validate_mandatory(self):
|
||||
# validate transaction date v/s delivery date
|
||||
if self.doc.delivery_date:
|
||||
if getdate(self.doc.transaction_date) > getdate(self.doc.delivery_date):
|
||||
msgprint("Expected Delivery Date cannot be before Sales Order Date")
|
||||
raise Exception
|
||||
# amendment date is necessary if document is amended
|
||||
if self.doc.amended_from and not self.doc.amendment_date:
|
||||
msgprint("Please Enter Amendment Date")
|
||||
raise Exception
|
||||
|
||||
|
||||
# Validate P.O Date
|
||||
# ------------------
|
||||
def validate_po(self):
|
||||
# validate p.o date v/s delivery date
|
||||
if self.doc.po_date and self.doc.delivery_date and getdate(self.doc.po_date) > getdate(self.doc.delivery_date):
|
||||
msgprint("Expected Delivery Date cannot be before Purchase Order Date")
|
||||
raise Exception
|
||||
|
||||
if self.doc.po_no and self.doc.customer:
|
||||
so = webnotes.conn.sql("select name from `tabSales Order` \
|
||||
where ifnull(po_no, '') = %s and name != %s and docstatus < 2\
|
||||
and customer = %s", (self.doc.po_no, self.doc.name, self.doc.customer))
|
||||
if so and so[0][0]:
|
||||
msgprint("""Another Sales Order (%s) exists against same PO No and Customer.
|
||||
Please be sure, you are not making duplicate entry.""" % so[0][0])
|
||||
|
||||
# Validations of Details Table
|
||||
# -----------------------------
|
||||
def validate_for_items(self):
|
||||
check_list,flag = [],0
|
||||
chk_dupl_itm = []
|
||||
# Sales Order Items Validations
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
if cstr(self.doc.quotation_no) == cstr(d.prevdoc_docname):
|
||||
flag = 1
|
||||
if d.prevdoc_docname:
|
||||
if self.doc.quotation_date and getdate(self.doc.quotation_date) > getdate(self.doc.transaction_date):
|
||||
msgprint("Sales Order Date cannot be before Quotation Date")
|
||||
raise Exception
|
||||
# validates whether quotation no in doctype and in table is same
|
||||
if not cstr(d.prevdoc_docname) == cstr(self.doc.quotation_no):
|
||||
msgprint("Items in table does not belong to the Quotation No mentioned.")
|
||||
raise Exception
|
||||
|
||||
# validates whether item is not entered twice
|
||||
e = [d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or '']
|
||||
f = [d.item_code, d.description]
|
||||
|
||||
#check item is stock item
|
||||
st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
|
||||
|
||||
if st_itm and st_itm[0][0] == 'Yes':
|
||||
if e in check_list:
|
||||
msgprint("Item %s has been entered twice." % d.item_code)
|
||||
else:
|
||||
check_list.append(e)
|
||||
elif st_itm and st_itm[0][0]== 'No':
|
||||
if f in chk_dupl_itm:
|
||||
msgprint("Item %s has been entered twice." % d.item_code)
|
||||
else:
|
||||
chk_dupl_itm.append(f)
|
||||
|
||||
# used for production plan
|
||||
d.transaction_date = self.doc.transaction_date
|
||||
d.delivery_date = self.doc.delivery_date
|
||||
|
||||
# gets total projected qty of item in warehouse selected (this case arises when warehouse is selected b4 item)
|
||||
tot_avail_qty = sql("select projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code,d.reserved_warehouse))
|
||||
d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
|
||||
|
||||
if flag == 0:
|
||||
msgprint("There are no items of the quotation selected.")
|
||||
raise Exception
|
||||
|
||||
# validate sales/ maintenance quotation against order type
|
||||
#------------------------------------------------------------------
|
||||
def validate_sales_mntc_quotation(self):
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
if d.prevdoc_docname:
|
||||
res = sql("select name from `tabQuotation` where name=%s and order_type = %s", (d.prevdoc_docname, self.doc.order_type))
|
||||
if not res:
|
||||
msgprint("""Order Type (%s) should be same in Quotation: %s \
|
||||
and current Sales Order""" % (self.doc.order_type, d.prevdoc_docname))
|
||||
|
||||
def validate_order_type(self):
|
||||
#validate delivery date
|
||||
if self.doc.order_type == 'Sales' and not self.doc.delivery_date:
|
||||
msgprint("Please enter 'Expected Delivery Date'")
|
||||
raise Exception
|
||||
|
||||
self.validate_sales_mntc_quotation()
|
||||
|
||||
#check for does customer belong to same project as entered..
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
def validate_proj_cust(self):
|
||||
if self.doc.project_name and self.doc.customer_name:
|
||||
res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
|
||||
if not res:
|
||||
msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name))
|
||||
raise Exception
|
||||
|
||||
|
||||
# Validate
|
||||
# ---------
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.validate_order_type()
|
||||
self.validate_mandatory()
|
||||
self.validate_proj_cust()
|
||||
self.validate_po()
|
||||
#self.validate_reference_value()
|
||||
self.validate_for_items()
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.check_conversion_rate(self)
|
||||
|
||||
# verify whether rate is not greater than max_discount
|
||||
sales_com_obj.validate_max_discount(self,'sales_order_details')
|
||||
# this is to verify that the allocated % of sales persons is 100%
|
||||
sales_com_obj.get_allocated_sum(self)
|
||||
self.doclist = sales_com_obj.make_packing_list(self,'sales_order_details')
|
||||
|
||||
# get total in words
|
||||
dcc = TransactionBase().get_company_currency(self.doc.company)
|
||||
self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total)
|
||||
self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
|
||||
|
||||
# set SO status
|
||||
self.doc.status='Draft'
|
||||
if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
|
||||
if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
|
||||
|
||||
|
||||
# ON SUBMIT
|
||||
# ===============================================================================================
|
||||
# Checks Quotation Status
|
||||
# ------------------------
|
||||
def check_prev_docstatus(self):
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
cancel_quo = sql("select name from `tabQuotation` where docstatus = 2 and name = '%s'" % d.prevdoc_docname)
|
||||
if cancel_quo:
|
||||
msgprint("Quotation :" + cstr(cancel_quo[0][0]) + " is already cancelled !")
|
||||
raise Exception , "Validation Error. "
|
||||
|
||||
def update_enquiry_status(self, prevdoc, flag):
|
||||
enq = sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.name=%s", prevdoc)
|
||||
if enq:
|
||||
sql("update `tabOpportunity` set status = %s where name=%s",(flag,enq[0][0]))
|
||||
|
||||
#update status of quotation, enquiry
|
||||
#----------------------------------------
|
||||
def update_prevdoc_status(self, flag):
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
if d.prevdoc_docname:
|
||||
if flag=='submit':
|
||||
sql("update `tabQuotation` set status = 'Order Confirmed' where name=%s",d.prevdoc_docname)
|
||||
|
||||
#update enquiry
|
||||
self.update_enquiry_status(d.prevdoc_docname, 'Order Confirmed')
|
||||
elif flag == 'cancel':
|
||||
chk = sql("select t1.name from `tabSales Order` t1, `tabSales Order Item` t2 where t2.parent = t1.name and t2.prevdoc_docname=%s and t1.name!=%s and t1.docstatus=1", (d.prevdoc_docname,self.doc.name))
|
||||
if not chk:
|
||||
sql("update `tabQuotation` set status = 'Submitted' where name=%s",d.prevdoc_docname)
|
||||
|
||||
#update enquiry
|
||||
self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent')
|
||||
|
||||
# Submit
|
||||
# -------
|
||||
def on_submit(self):
|
||||
self.check_prev_docstatus()
|
||||
self.update_stock_ledger(update_stock = 1)
|
||||
self.set_sms_msg(1)
|
||||
# update customer's last sales order no.
|
||||
update_customer = sql("update `tabCustomer` set last_sales_order = '%s', modified = '%s' where name = '%s'" %(self.doc.name, self.doc.modified, self.doc.customer))
|
||||
get_obj('Sales Common').check_credit(self,self.doc.grand_total)
|
||||
|
||||
# Check for Approving Authority
|
||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self)
|
||||
|
||||
#update prevdoc status
|
||||
self.update_prevdoc_status('submit')
|
||||
# set SO status
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
|
||||
# ON CANCEL
|
||||
# ===============================================================================================
|
||||
def on_cancel(self):
|
||||
# Cannot cancel stopped SO
|
||||
if self.doc.status == 'Stopped':
|
||||
msgprint("Sales Order : '%s' cannot be cancelled as it is Stopped. Unstop it for any further transactions" %(self.doc.name))
|
||||
raise Exception
|
||||
self.check_nextdoc_docstatus()
|
||||
self.update_stock_ledger(update_stock = -1)
|
||||
self.set_sms_msg()
|
||||
|
||||
#update prevdoc status
|
||||
self.update_prevdoc_status('cancel')
|
||||
|
||||
# ::::::::: SET SO STATUS ::::::::::
|
||||
set(self.doc, 'status', 'Cancelled')
|
||||
|
||||
# CHECK NEXT DOCSTATUS
|
||||
# does not allow to cancel document if DN or RV made against it is SUBMITTED
|
||||
# ----------------------------------------------------------------------------
|
||||
def check_nextdoc_docstatus(self):
|
||||
# Checks Delivery Note
|
||||
submit_dn = sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Item` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||
if submit_dn:
|
||||
msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
# Checks Sales Invoice
|
||||
submit_rv = sql("select t1.name from `tabSales Invoice` t1,`tabSales Invoice Item` t2 where t1.name = t2.parent and t2.sales_order = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||
if submit_rv:
|
||||
msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
#check maintenance schedule
|
||||
submit_ms = sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
|
||||
if submit_ms:
|
||||
msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
submit_mv = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
|
||||
if submit_mv:
|
||||
msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
|
||||
|
||||
def check_modified_date(self):
|
||||
mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name)
|
||||
date_diff = sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.doc.modified)))
|
||||
|
||||
if date_diff and date_diff[0][0]:
|
||||
msgprint(cstr(self.doc.doctype) +" => "+ cstr(self.doc.name) +" has been modified. Please Refresh. ")
|
||||
raise Exception
|
||||
|
||||
# STOP SALES ORDER
|
||||
# ==============================================================================================
|
||||
# Stops Sales Order & no more transactions will be created against this Sales Order
|
||||
def stop_sales_order(self):
|
||||
self.check_modified_date()
|
||||
self.update_stock_ledger(update_stock = -1,clear = 1)
|
||||
# ::::::::: SET SO STATUS ::::::::::
|
||||
set(self.doc, 'status', 'Stopped')
|
||||
msgprint(self.doc.doctype + ": " + self.doc.name + " has been Stopped. To make transactions against this Sales Order you need to Unstop it.")
|
||||
|
||||
# UNSTOP SALES ORDER
|
||||
# ==============================================================================================
|
||||
# Unstops Sales Order & now transactions can be continued against this Sales Order
|
||||
def unstop_sales_order(self):
|
||||
self.check_modified_date()
|
||||
self.update_stock_ledger(update_stock = 1,clear = 1)
|
||||
# ::::::::: SET SO STATUS ::::::::::
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
msgprint(self.doc.doctype + ": " + self.doc.name + " has been Unstopped.")
|
||||
|
||||
# UPDATE STOCK LEDGER
|
||||
# ===============================================================================================
|
||||
def update_stock_ledger(self, update_stock, clear = 0):
|
||||
for d in self.get_item_list(clear):
|
||||
stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d['item_code']),as_dict = 1)
|
||||
# stock ledger will be updated only if it is a stock item
|
||||
if stock_item and stock_item[0]['is_stock_item'] == "Yes":
|
||||
if not d['reserved_warehouse']:
|
||||
msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d['item_code'])
|
||||
raise Exception
|
||||
bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin( 0, flt(update_stock) * flt(d['qty']), \
|
||||
0, 0, 0, d['item_code'], self.doc.transaction_date,doc_type=self.doc.doctype,\
|
||||
doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
|
||||
|
||||
# Gets Items from packing list
|
||||
#=================================
|
||||
def get_item_list(self, clear):
|
||||
return get_obj('Sales Common').get_item_list( self, clear)
|
||||
|
||||
# SET MESSAGE FOR SMS
|
||||
#======================
|
||||
def set_sms_msg(self, is_submitted = 0):
|
||||
if is_submitted:
|
||||
if not self.doc.amended_from:
|
||||
msg = 'Sales Order: '+self.doc.name+' has been made against PO no: '+cstr(self.doc.po_no)
|
||||
set(self.doc, 'message', msg)
|
||||
else:
|
||||
msg = 'Sales Order has been amended. New SO no:'+self.doc.name
|
||||
set(self.doc, 'message', msg)
|
||||
else:
|
||||
msg = 'Sales Order: '+self.doc.name+' has been cancelled.'
|
||||
set(self.doc, 'message', msg)
|
||||
|
||||
# SEND SMS
|
||||
# =========
|
||||
def send_sms(self):
|
||||
if not self.doc.customer_mobile_no:
|
||||
msgprint("Please enter customer mobile no")
|
||||
elif not self.doc.message:
|
||||
msgprint("Please enter the message you want to send")
|
||||
else:
|
||||
msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message))
|
||||
|
||||
# on update
|
||||
def on_update(self):
|
||||
pass
|
||||
|
||||
1375
selling/doctype/sales_order/sales_order.txt
Normal file
1375
selling/doctype/sales_order/sales_order.txt
Normal file
File diff suppressed because it is too large
Load Diff
50
selling/doctype/sales_order/sales_order_list.js
Normal file
50
selling/doctype/sales_order/sales_order_list.js
Normal file
@@ -0,0 +1,50 @@
|
||||
// render
|
||||
wn.doclistviews['Sales Order'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabSales Order`.customer_name",
|
||||
"`tabSales Order`.status",
|
||||
"`tabSales Order`.order_type",
|
||||
"ifnull(`tabSales Order`.per_delivered,0) as per_delivered",
|
||||
"ifnull(`tabSales Order`.per_billed,0) as per_billed",
|
||||
"`tabSales Order`.currency",
|
||||
"ifnull(`tabSales Order`.grand_total_export,0) as grand_total_export",
|
||||
"`tabSales Order`.transaction_date",
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'order_type', 'company']);
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content: 'avatar'},
|
||||
{width: '3%', content: 'docstatus'},
|
||||
{width: '15%', content: 'name'},
|
||||
{width: '29%', content: 'customer_name+tags', css: {color:'#222'}},
|
||||
{
|
||||
width: '18%',
|
||||
content: function(parent, data) {
|
||||
$(parent).html(data.currency + ' ' + fmt_money(data.grand_total_export))
|
||||
},
|
||||
css: {'text-align':'right'}
|
||||
},
|
||||
{
|
||||
width: '11%',
|
||||
content: function(parent, data, me) {
|
||||
var order_type = data.order_type.toLowerCase();
|
||||
|
||||
if (order_type === 'sales') {
|
||||
me.render_icon(parent, 'icon-tag', data.order_type);
|
||||
me.render_bar_graph(parent, data, 'per_delivered', 'Delivered');
|
||||
} else if (order_type === 'maintenance') {
|
||||
me.render_icon(parent, 'icon-wrench', data.order_type);
|
||||
}
|
||||
},
|
||||
},
|
||||
{width: '8%', content: 'per_billed', type:'bar-graph', label:'Billed'},
|
||||
{width: '12%', content:'transaction_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Sales Order Date", type: "date"}
|
||||
]
|
||||
|
||||
});
|
||||
1
selling/doctype/sales_order_item/__init__.py
Normal file
1
selling/doctype/sales_order_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
444
selling/doctype/sales_order_item/sales_order_item.txt
Normal file
444
selling/doctype/sales_order_item/sales_order_item.txt
Normal file
@@ -0,0 +1,444 @@
|
||||
# DocType, Sales Order Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-06-08 16:07:58',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-09 11:05:16',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'SOD/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales Order Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Sales Order Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales Order Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_item_code',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u"Customer's Item Code",
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Item Name',
|
||||
'oldfieldname': u'item_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'width': u'150'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Small Text',
|
||||
'in_filter': 1,
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Quantity',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate',
|
||||
'oldfieldname': u'ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'adj_rate',
|
||||
'fieldtype': u'Float',
|
||||
'label': u'Discount(%)',
|
||||
'oldfieldname': u'adj_rate',
|
||||
'oldfieldtype': u'Float',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'export_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'export_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'base_ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate*',
|
||||
'oldfieldname': u'base_ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Basic Rate*',
|
||||
'oldfieldname': u'basic_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount*',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'reserved_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Reserved Warehouse',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'reserved_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'projected_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Projected Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'projected_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'actual_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Actual Qty',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivered_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Delivered Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'delivered_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'billed_amt',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Billed Amt',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'For Production',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'planned_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Planned Quantity',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'planned_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'For Production',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'produced_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Produced Quantity',
|
||||
'oldfieldname': u'produced_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Brand Name',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Item Group',
|
||||
'oldfieldname': u'item_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item Group',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Quotation No.',
|
||||
'oldfieldname': u'prevdoc_docname',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Quotation',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 1,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'page_break',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Page Break',
|
||||
'oldfieldname': u'page_break',
|
||||
'oldfieldtype': u'Check',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_tax_rate',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 1,
|
||||
'label': u'Item Tax Rate',
|
||||
'oldfieldname': u'item_tax_rate',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The date at which current entry is made in system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transaction_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Sales Order Date',
|
||||
'oldfieldname': u'transaction_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'search_index': 0
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sales_team/__init__.py
Normal file
1
selling/doctype/sales_team/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
128
selling/doctype/sales_team/sales_team.txt
Normal file
128
selling/doctype/sales_team/sales_team.txt
Normal file
@@ -0,0 +1,128 @@
|
||||
# DocType, Sales Team
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:17',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:17',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 5
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales Team',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Sales Team
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales Team'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'sales_person',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Sales Person',
|
||||
'oldfieldname': u'sales_person',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Sales Person',
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'width': u'200px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'sales_designation',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Designation',
|
||||
'oldfieldname': u'sales_designation',
|
||||
'oldfieldtype': u'Data',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_no',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Contact No.',
|
||||
'oldfieldname': u'contact_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'allocated_percentage',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Allocated (%)',
|
||||
'oldfieldname': u'allocated_percentage',
|
||||
'oldfieldtype': u'Currency',
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'allocated_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Allocated Amount',
|
||||
'oldfieldname': u'allocated_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'reqd': 0,
|
||||
'width': u'120px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'parenttype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Parenttype',
|
||||
'oldfieldname': u'parenttype',
|
||||
'oldfieldtype': u'Data',
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'incentives',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Incentives',
|
||||
'oldfieldname': u'incentives',
|
||||
'oldfieldtype': u'Currency'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/shipping_address/__init__.py
Executable file
1
selling/doctype/shipping_address/__init__.py
Executable file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
20
selling/doctype/shipping_address/shipping_address.js
Executable file
20
selling/doctype/shipping_address/shipping_address.js
Executable file
@@ -0,0 +1,20 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Get Customer Details
|
||||
// =====================================================================
|
||||
cur_frm.add_fetch('customer','customer_name','customer_name');
|
||||
cur_frm.add_fetch('customer','address','customer_address');
|
||||
42
selling/doctype/shipping_address/shipping_address.py
Executable file
42
selling/doctype/shipping_address/shipping_address.py
Executable file
@@ -0,0 +1,42 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
# on update
|
||||
# ----------
|
||||
def on_update(self):
|
||||
self.update_primary_shipping_address()
|
||||
self.get_customer_details()
|
||||
|
||||
# set is_primary_address for other shipping addresses belonging to same customer
|
||||
# -------------------------------------------------------------------------------
|
||||
def update_primary_shipping_address(self):
|
||||
if self.doc.is_primary_address == 'Yes':
|
||||
sql("update `tabShipping Address` set is_primary_address = 'No' where customer = %s and is_primary_address = 'Yes' and name != %s",(self.doc.customer, self.doc.name))
|
||||
|
||||
# Get Customer Details
|
||||
# ---------------------
|
||||
def get_customer_details(self):
|
||||
det = sql("select customer_name, address from tabCustomer where name = '%s'" % (self.doc.customer))
|
||||
self.doc.customer_name = det and det[0][0] or ''
|
||||
self.doc.customer_address = det and det[0][1] or ''
|
||||
181
selling/doctype/shipping_address/shipping_address.txt
Executable file
181
selling/doctype/shipping_address/shipping_address.txt
Executable file
@@ -0,0 +1,181 @@
|
||||
# DocType, Shipping Address
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:17',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:17',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'allow_trash': 1,
|
||||
'autoname': u'SA.#####',
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'search_fields': u'customer, ship_to, shipping_address',
|
||||
'section_style': u'Simple',
|
||||
'show_in_menu': 0,
|
||||
'version': 8
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Shipping Address',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Shipping Address',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Shipping Address
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Shipping Address'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Master Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Customer Name',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Customer Address',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ship_to',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Ship To',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'shipping_address',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Shipping Address',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'is_primary_address',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Is Primary Address',
|
||||
'options': u'Yes\nNo',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'shipping_details',
|
||||
'fieldtype': u'Text Editor',
|
||||
'label': u'Shipping Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'permlevel': 1
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sms_center/__init__.py
Normal file
1
selling/doctype/sms_center/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
82
selling/doctype/sms_center/sms_center.py
Normal file
82
selling/doctype/sms_center/sms_center.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
# ----------
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
def create_receiver_list(self):
|
||||
rec, where_clause = '', ''
|
||||
if self.doc.send_to == 'All Customer Contact':
|
||||
where_clause = self.doc.customer and " and customer = '%s'" % self.doc.customer or " and ifnull(is_customer, 0) = 1"
|
||||
if self.doc.send_to == 'All Supplier Contact':
|
||||
where_clause = self.doc.supplier and " and ifnull(is_supplier, 0) = 1 and supplier = '%s'" % self.doc.supplier or " and ifnull(is_supplier, 0) = 1"
|
||||
if self.doc.send_to == 'All Sales Partner Contact':
|
||||
where_clause = self.doc.sales_partner and " and ifnull(is_sales_partner, 0) = 1 and sales_aprtner = '%s'" % self.doc.sales_partner or " and ifnull(is_sales_partner, 0) = 1"
|
||||
if self.doc.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']:
|
||||
rec = sql("select CONCAT(ifnull(first_name,''),'',ifnull(last_name,'')), mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and docstatus != 2 %s" % where_clause)
|
||||
elif self.doc.send_to == 'All Lead (Open)':
|
||||
rec = sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'")
|
||||
elif self.doc.send_to == 'All Employee (Active)':
|
||||
where_clause = self.doc.department and " and t1.department = '%s'" % self.doc.department or ""
|
||||
where_clause += self.doc.branch and " and t1.branch = '%s'" % self.doc.branch or ""
|
||||
rec = sql("select t1.employee_name, t2.cell_number from `tabEmployee` t1, `tabEmployee Profile` t2 where t2.employee = t1.name and t1.status = 'Active' and t1.docstatus != 2 and ifnull(t2.cell_number,'')!='' %s" % where_clause)
|
||||
elif self.doc.send_to == 'All Sales Person':
|
||||
rec = sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''")
|
||||
|
||||
rec_list = ''
|
||||
for d in rec:
|
||||
rec_list += d[0] + ' - ' + d[1] + '\n'
|
||||
self.doc.receiver_list = rec_list
|
||||
|
||||
def get_receiver_nos(self):
|
||||
receiver_nos = []
|
||||
for d in self.doc.receiver_list.split('\n'):
|
||||
receiver_no = d
|
||||
if '-' in d:
|
||||
receiver_no = receiver_no.split('-')[1]
|
||||
if receiver_no.strip():
|
||||
receiver_nos.append(cstr(receiver_no).strip())
|
||||
return receiver_nos
|
||||
|
||||
def send_sms(self):
|
||||
if not self.doc.message:
|
||||
msgprint("Please enter message before sending")
|
||||
else:
|
||||
receiver_list = self.get_receiver_nos()
|
||||
if receiver_list:
|
||||
msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, cstr(self.doc.message)))
|
||||
185
selling/doctype/sms_center/sms_center.txt
Normal file
185
selling/doctype/sms_center/sms_center.txt
Normal file
@@ -0,0 +1,185 @@
|
||||
# DocType, SMS Center
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:17',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:17',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1322549700',
|
||||
'allow_attach': 0,
|
||||
'allow_copy': 1,
|
||||
'allow_email': 1,
|
||||
'allow_print': 1,
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'hide_heading': 0,
|
||||
'hide_toolbar': 0,
|
||||
'in_create': 0,
|
||||
'issingle': 1,
|
||||
'menu_index': 4,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'read_only': 1,
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 1,
|
||||
'version': 41
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'SMS Center',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'SMS Center',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocType, SMS Center
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'SMS Center'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'send_to',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Send To',
|
||||
'options': u'\nAll Contact\nAll Customer Contact\nAll Supplier Contact\nAll Sales Partner Contact\nAll Lead (Open)\nAll Employee (Active)\nAll Sales Person',
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Customer Contact'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer',
|
||||
'options': u'Customer'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Supplier Contact'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Supplier',
|
||||
'options': u'Supplier'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Employee (Active)'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'department',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Department',
|
||||
'options': u'link:Department'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Employee (Active)'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'branch',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Branch',
|
||||
'options': u'link:Branch'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'create_receiver_list',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Create Receiver List',
|
||||
'options': u'create_receiver_list'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'receiver_list',
|
||||
'fieldtype': u'Code',
|
||||
'label': u'Receiver List'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break9',
|
||||
'fieldtype': u'Column Break',
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'description': u'Message greater than 160 character will be splitted into multiple mesage',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'message',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Message',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'send_sms',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Send SMS',
|
||||
'options': u'send_sms'
|
||||
}
|
||||
]
|
||||
1
selling/page/__init__.py
Normal file
1
selling/page/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
0
selling/page/sales_analytics/__init__.py
Normal file
0
selling/page/sales_analytics/__init__.py
Normal file
264
selling/page/sales_analytics/sales_analytics.js
Normal file
264
selling/page/sales_analytics/sales_analytics.js
Normal file
@@ -0,0 +1,264 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
wn.pages['sales-analytics'].onload = function(wrapper) {
|
||||
wn.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: 'Sales Analytics',
|
||||
single_column: true
|
||||
});
|
||||
new erpnext.SalesAnalytics(wrapper);
|
||||
}
|
||||
|
||||
erpnext.SalesAnalytics = wn.views.TreeGridReport.extend({
|
||||
init: function(wrapper) {
|
||||
this._super({
|
||||
title: "Sales Analytics",
|
||||
page: wrapper,
|
||||
parent: $(wrapper).find('.layout-main'),
|
||||
appframe: wrapper.appframe,
|
||||
doctypes: ["Item", "Item Group", "Customer", "Customer Group", "Company",
|
||||
"Sales Invoice", "Sales Invoice Item", "Territory"],
|
||||
tree_grid: { show: true }
|
||||
});
|
||||
|
||||
this.tree_grids = {
|
||||
"Customer Group": {
|
||||
label: "Customer Group / Customer",
|
||||
show: true,
|
||||
item_key: "customer",
|
||||
parent_field: "parent_customer_group",
|
||||
formatter: function(item) {
|
||||
// return repl('<a href="#Report2/stock-invoices/customer=%(enc_value)s">%(value)s</a>', {
|
||||
// value: item.name,
|
||||
// enc_value: encodeURIComponent(item.name)
|
||||
// });
|
||||
return item.name;
|
||||
}
|
||||
},
|
||||
"Customer": {
|
||||
label: "Customer",
|
||||
show: false,
|
||||
item_key: "customer",
|
||||
formatter: function(item) {
|
||||
return item.name;
|
||||
}
|
||||
},
|
||||
"Item Group": {
|
||||
label: "Item",
|
||||
show: true,
|
||||
parent_field: "parent_item_group",
|
||||
item_key: "item_code",
|
||||
formatter: function(item) {
|
||||
return item.name;
|
||||
}
|
||||
},
|
||||
"Item": {
|
||||
label: "Item",
|
||||
show: false,
|
||||
item_key: "item_code",
|
||||
formatter: function(item) {
|
||||
return item.name;
|
||||
}
|
||||
},
|
||||
"Territory": {
|
||||
label: "Territory / Customer",
|
||||
show: true,
|
||||
item_key: "customer",
|
||||
parent_field: "parent_territory",
|
||||
formatter: function(item) {
|
||||
return item.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
setup_columns: function() {
|
||||
this.tree_grid = this.tree_grids[this.tree_type];
|
||||
|
||||
var std_columns = [
|
||||
{id: "check", name: "Plot", field: "check", width: 30,
|
||||
formatter: this.check_formatter},
|
||||
{id: "name", name: this.tree_grid.label, field: "name", width: 300,
|
||||
formatter: this.tree_formatter},
|
||||
{id: "total", name: "Total", field: "total", plot: false,
|
||||
formatter: this.currency_formatter}
|
||||
];
|
||||
|
||||
this.make_date_range_columns();
|
||||
this.columns = std_columns.concat(this.columns);
|
||||
},
|
||||
filters: [
|
||||
{fieldtype:"Select", label: "Tree Type", options:["Customer Group", "Customer",
|
||||
"Item Group", "Item", "Territory"],
|
||||
filter: function(val, item, opts, me) {
|
||||
return me.apply_zero_filter(val, item, opts, me);
|
||||
}},
|
||||
{fieldtype:"Select", label: "Value or Qty", options:["Value", "Quantity"]},
|
||||
{fieldtype:"Select", label: "Company", link:"Company",
|
||||
default_value: "Select Company..."},
|
||||
{fieldtype:"Date", label: "From Date"},
|
||||
{fieldtype:"Label", label: "To"},
|
||||
{fieldtype:"Date", label: "To Date"},
|
||||
{fieldtype:"Select", label: "Range",
|
||||
options:["Daily", "Weekly", "Monthly", "Quarterly", "Yearly"]},
|
||||
{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
|
||||
{fieldtype:"Button", label: "Reset Filters"}
|
||||
],
|
||||
setup_filters: function() {
|
||||
var me = this;
|
||||
this._super();
|
||||
|
||||
this.filter_inputs.value_or_qty.change(function() {
|
||||
me.filter_inputs.refresh.click();
|
||||
});
|
||||
|
||||
this.filter_inputs.tree_type.change(function() {
|
||||
me.filter_inputs.refresh.click();
|
||||
});
|
||||
|
||||
this.show_zero_check()
|
||||
this.setup_plot_check();
|
||||
},
|
||||
init_filter_values: function() {
|
||||
this._super();
|
||||
this.filter_inputs.range.val('Weekly');
|
||||
},
|
||||
prepare_data: function() {
|
||||
var me = this;
|
||||
if (!this.tl) {
|
||||
this.make_transaction_list("Sales Invoice", "Sales Invoice Item");
|
||||
|
||||
// add 'Not Set' Customer & Item
|
||||
// (Customer / Item are not mandatory!!)
|
||||
wn.report_dump.data["Customer"].push({
|
||||
name: "Not Set",
|
||||
parent_customer_group: "All Customer Groups",
|
||||
parent_territory: "All Territories",
|
||||
id: "Not Set",
|
||||
});
|
||||
|
||||
wn.report_dump.data["Item"].push({
|
||||
name: "Not Set",
|
||||
parent_item_group: "All Item Groups",
|
||||
id: "Not Set",
|
||||
});
|
||||
}
|
||||
|
||||
if(!this.data || me.item_type != me.tree_type) {
|
||||
if(me.tree_type=='Customer') {
|
||||
var items = wn.report_dump.data["Customer"];
|
||||
} if(me.tree_type=='Customer Group') {
|
||||
var items = this.prepare_tree("Customer", "Customer Group");
|
||||
} else if(me.tree_type=="Item Group") {
|
||||
var items = this.prepare_tree("Item", "Item Group");
|
||||
} else if(me.tree_type=="Item") {
|
||||
var items = wn.report_dump.data["Item"];
|
||||
} else if(me.tree_type=="Territory") {
|
||||
var items = this.prepare_tree("Customer", "Territory");
|
||||
}
|
||||
|
||||
me.item_type = me.tree_type
|
||||
me.parent_map = {};
|
||||
me.item_by_name = {};
|
||||
me.data = [];
|
||||
|
||||
$.each(items, function(i, v) {
|
||||
var d = copy_dict(v);
|
||||
|
||||
me.data.push(d);
|
||||
me.item_by_name[d.name] = d;
|
||||
if(d[me.tree_grid.parent_field]) {
|
||||
me.parent_map[d.name] = d[me.tree_grid.parent_field];
|
||||
}
|
||||
me.reset_item_values(d);
|
||||
});
|
||||
|
||||
this.set_indent();
|
||||
|
||||
} else {
|
||||
// otherwise, only reset values
|
||||
$.each(this.data, function(i, d) {
|
||||
me.reset_item_values(d);
|
||||
});
|
||||
}
|
||||
|
||||
this.prepare_balances();
|
||||
if(me.tree_grid.show) {
|
||||
this.set_totals(false);
|
||||
this.update_groups();
|
||||
} else {
|
||||
this.set_totals(true);
|
||||
}
|
||||
|
||||
},
|
||||
prepare_balances: function() {
|
||||
var me = this;
|
||||
var from_date = dateutil.str_to_obj(this.from_date);
|
||||
var to_date = dateutil.str_to_obj(this.to_date);
|
||||
var is_val = this.value_or_qty == 'Value';
|
||||
|
||||
$.each(this.tl, function(i, tl) {
|
||||
if (me.is_default('company') ? true : me.apply_filter(tl, "company")) {
|
||||
var posting_date = dateutil.str_to_obj(tl.posting_date);
|
||||
if (posting_date >= from_date && posting_date <= to_date) {
|
||||
var item = me.item_by_name[tl[me.tree_grid.item_key]] || me.item_by_name['Not Set'];
|
||||
item[me.column_map[tl.posting_date].field] += (is_val ? tl.amount : tl.qty);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
update_groups: function() {
|
||||
var me = this;
|
||||
|
||||
$.each(this.data, function(i, item) {
|
||||
var parent = me.parent_map[item.name];
|
||||
while(parent) {
|
||||
parent_group = me.item_by_name[parent];
|
||||
|
||||
$.each(me.columns, function(c, col) {
|
||||
if (col.formatter == me.currency_formatter) {
|
||||
parent_group[col.field] =
|
||||
flt(parent_group[col.field])
|
||||
+ flt(item[col.field]);
|
||||
}
|
||||
});
|
||||
parent = me.parent_map[parent];
|
||||
}
|
||||
});
|
||||
},
|
||||
set_totals: function(sort) {
|
||||
var me = this;
|
||||
var checked = false;
|
||||
$.each(this.data, function(i, d) {
|
||||
d.total = 0.0;
|
||||
$.each(me.columns, function(i, col) {
|
||||
if(col.formatter==me.currency_formatter && !col.hidden && col.field!="total")
|
||||
d.total += d[col.field];
|
||||
if(d.checked) checked = true;
|
||||
})
|
||||
});
|
||||
|
||||
if(sort)this.data = this.data.sort(function(a, b) { return a.total < b.total; });
|
||||
|
||||
if(!this.checked) {
|
||||
this.data[0].checked = true;
|
||||
}
|
||||
},
|
||||
get_plot_points: function(item, col, idx) {
|
||||
return [[dateutil.str_to_obj(col.id).getTime(), item[col.field]],
|
||||
[dateutil.user_to_obj(col.name).getTime(), item[col.field]]];
|
||||
}
|
||||
});
|
||||
28
selling/page/sales_analytics/sales_analytics.txt
Normal file
28
selling/page/sales_analytics/sales_analytics.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
# Page, sales-analytics
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-09-21 12:06:14',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-09-21 12:06:14',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
u'doctype': u'Page',
|
||||
'module': u'Selling',
|
||||
u'name': u'__common__',
|
||||
'page_name': u'sales-analytics',
|
||||
'standard': u'Yes',
|
||||
'title': u'Sales Analytics'
|
||||
},
|
||||
|
||||
# Page, sales-analytics
|
||||
{
|
||||
u'doctype': u'Page',
|
||||
u'name': u'sales-analytics'
|
||||
}
|
||||
]
|
||||
1
selling/page/sales_browser/__init__.py
Normal file
1
selling/page/sales_browser/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
14
selling/page/sales_browser/sales_browser.css
Normal file
14
selling/page/sales_browser/sales_browser.css
Normal file
@@ -0,0 +1,14 @@
|
||||
span.tree-node-toolbar {
|
||||
padding: 2px;
|
||||
margin-left: 15px;
|
||||
border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tree-area a.selected {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
11
selling/page/sales_browser/sales_browser.html
Normal file
11
selling/page/sales_browser/sales_browser.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="layout-wrapper layout-wrapper-background">
|
||||
<div class="appframe-area"></div>
|
||||
<div class="layout-main-section">
|
||||
<div class="tree-area"></div>
|
||||
</div>
|
||||
<div class="layout-side-section">
|
||||
<div class="help">To add child nodes, explore tree and click on the node under which you want to add more nodes.
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
144
selling/page/sales_browser/sales_browser.js
Normal file
144
selling/page/sales_browser/sales_browser.js
Normal file
@@ -0,0 +1,144 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pscript['onload_Sales Browser'] = function(wrapper){
|
||||
wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'));
|
||||
wrapper.appframe.add_button('Refresh', function() {
|
||||
wrapper.make_tree();
|
||||
}, 'icon-refresh');
|
||||
|
||||
wrapper.make_tree = function() {
|
||||
var ctype = wn.get_route()[1] || 'Territory';
|
||||
erpnext.sales_chart = new erpnext.SalesChart(ctype, wrapper);
|
||||
}
|
||||
|
||||
wrapper.make_tree();
|
||||
}
|
||||
|
||||
pscript['onshow_Sales Browser'] = function(wrapper){
|
||||
// set route
|
||||
var ctype = wn.get_route()[1] || 'Territory';
|
||||
|
||||
wrapper.appframe.clear_breadcrumbs();
|
||||
wrapper.appframe.add_breadcrumb(ctype+' Tree')
|
||||
document.title = ctype+' Tree';
|
||||
|
||||
wrapper.appframe.add_breadcrumb(' in <a href="#!selling-home">Selling</a>');
|
||||
|
||||
if(erpnext.sales_chart && erpnext.sales_chart.ctype != ctype) {
|
||||
wrapper.make_tree();
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.SalesChart = Class.extend({
|
||||
init: function(ctype, wrapper) {
|
||||
var root_nodes = {
|
||||
'Territory': 'All Territories',
|
||||
'Item Group': 'All Item Groups',
|
||||
'Customer Group': 'All Customer Groups',
|
||||
'Sales Person': 'All Sales Persons'
|
||||
}
|
||||
|
||||
$(wrapper).find('.tree-area').empty();
|
||||
var me = this;
|
||||
me.ctype = ctype;
|
||||
this.tree = new wn.ui.Tree({
|
||||
parent: $(wrapper).find('.tree-area'),
|
||||
label: root_nodes[ctype],
|
||||
args: {ctype: ctype},
|
||||
method: 'selling.page.sales_browser.sales_browser.get_children',
|
||||
click: function(link) {
|
||||
if(me.cur_toolbar)
|
||||
$(me.cur_toolbar).toggle(false);
|
||||
|
||||
if(!link.toolbar)
|
||||
me.make_link_toolbar(link);
|
||||
|
||||
if(link.toolbar) {
|
||||
me.cur_toolbar = link.toolbar;
|
||||
$(me.cur_toolbar).toggle(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.tree.rootnode.$a
|
||||
.data('node-data', {value: root_nodes[ctype], expandable:1})
|
||||
.click();
|
||||
},
|
||||
make_link_toolbar: function(link) {
|
||||
var data = $(link).data('node-data');
|
||||
if(!data) return;
|
||||
|
||||
link.toolbar = $('<span class="tree-node-toolbar"></span>').insertAfter(link);
|
||||
|
||||
// edit
|
||||
var node_links = [];
|
||||
|
||||
if (wn.boot.profile.can_read.indexOf(this.ctype) !== -1) {
|
||||
node_links.push('<a href="#!Form/'+encodeURIComponent(this.ctype)+'/'
|
||||
+encodeURIComponent(data.value)+'">Edit</a>');
|
||||
}
|
||||
|
||||
if(data.expandable) {
|
||||
if (wn.boot.profile.can_create.indexOf(this.ctype) !== -1 ||
|
||||
wn.boot.profile.in_create.indexOf(this.ctype) !== -1) {
|
||||
node_links.push('<a onclick="erpnext.sales_chart.new_node();">Add Child</a>');
|
||||
}
|
||||
}
|
||||
|
||||
link.toolbar.append(node_links.join(" | "));
|
||||
},
|
||||
new_node: function() {
|
||||
var me = this;
|
||||
|
||||
// the dialog
|
||||
var d = new wn.ui.Dialog({
|
||||
title:'New ' + me.ctype,
|
||||
fields: [
|
||||
{fieldtype:'Data', fieldname: 'name_field', label:'New ' + me.ctype + ' Name', reqd:true},
|
||||
{fieldtype:'Select', fieldname:'is_group', label:'Group Node',
|
||||
options:'No\nYes', description:'Entries can made only against non-group (leaf) nodes'},
|
||||
{fieldtype:'Button', fieldname:'create_new', label:'Create New' }
|
||||
]
|
||||
})
|
||||
|
||||
// create
|
||||
$(d.fields_dict.create_new.input).click(function() {
|
||||
var btn = this;
|
||||
$(btn).set_working();
|
||||
var v = d.get_values();
|
||||
if(!v) return;
|
||||
|
||||
var node = me.selected_node();
|
||||
|
||||
v.parent = node.data('label');
|
||||
v.ctype = me.ctype;
|
||||
|
||||
wn.call({
|
||||
method: 'selling.page.sales_browser.sales_browser.add_node',
|
||||
args: v,
|
||||
callback: function() {
|
||||
$(btn).done_working();
|
||||
d.hide();
|
||||
node.trigger('reload');
|
||||
}
|
||||
})
|
||||
});
|
||||
d.show();
|
||||
},
|
||||
selected_node: function() {
|
||||
return this.tree.$w.find('.tree-link.selected');
|
||||
}
|
||||
});
|
||||
26
selling/page/sales_browser/sales_browser.py
Normal file
26
selling/page/sales_browser/sales_browser.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_children():
|
||||
ctype = webnotes.form_dict.get('ctype')
|
||||
webnotes.form_dict['parent_field'] = 'parent_' + ctype.lower().replace(' ', '_')
|
||||
|
||||
return webnotes.conn.sql("""select name as value,
|
||||
if(is_group='Yes', 1, 0) as expandable
|
||||
from `tab%(ctype)s`
|
||||
where docstatus < 2
|
||||
and %(parent_field)s = "%(parent)s"
|
||||
order by name""" % webnotes.form_dict, as_dict=1)
|
||||
|
||||
@webnotes.whitelist()
|
||||
def add_node():
|
||||
from webnotes.model.doc import Document
|
||||
ctype = webnotes.form_dict.get('ctype')
|
||||
parent_field = 'parent_' + ctype.lower().replace(' ', '_')
|
||||
|
||||
d = Document(ctype)
|
||||
d.fields[ctype.lower().replace(' ', '_') + '_name'] = webnotes.form_dict['name_field']
|
||||
d.fields[parent_field] = webnotes.form_dict['parent']
|
||||
d.is_group = webnotes.form_dict['is_group']
|
||||
d.save()
|
||||
51
selling/page/sales_browser/sales_browser.txt
Normal file
51
selling/page/sales_browser/sales_browser.txt
Normal file
@@ -0,0 +1,51 @@
|
||||
# Page, Sales Browser
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-12-14 10:23:21',
|
||||
'docstatus': 0,
|
||||
'modified': '2010-12-24 11:56:34',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'module': 'Selling',
|
||||
'name': '__common__',
|
||||
'page_name': 'Sales Browser',
|
||||
'show_in_menu': 0,
|
||||
'standard': 'Yes'
|
||||
},
|
||||
|
||||
# These values are common for all Page Role
|
||||
{
|
||||
'doctype': 'Page Role',
|
||||
'name': '__common__',
|
||||
'parent': 'Sales Browser',
|
||||
'parentfield': 'roles',
|
||||
'parenttype': 'Page'
|
||||
},
|
||||
|
||||
# Page, Sales Browser
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'name': 'Sales Browser'
|
||||
},
|
||||
|
||||
# Page Role
|
||||
{
|
||||
'doctype': 'Page Role',
|
||||
'idx': 1,
|
||||
'role': 'Sales Master Manager'
|
||||
},
|
||||
|
||||
# Page Role
|
||||
{
|
||||
'doctype': 'Page Role',
|
||||
'idx': 2,
|
||||
'role': 'Material Master Manager'
|
||||
}
|
||||
]
|
||||
1
selling/page/selling_home/__init__.py
Normal file
1
selling/page/selling_home/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
125
selling/page/selling_home/selling_home.html
Normal file
125
selling/page/selling_home/selling_home.html
Normal file
@@ -0,0 +1,125 @@
|
||||
<div class="layout-wrapper layout-wrapper-background">
|
||||
<div class="appframe-area"></div>
|
||||
<div class="layout-main-section">
|
||||
<div style="width: 48%; float: left;">
|
||||
<h4><a href="#!List/Lead">Lead</a></h4>
|
||||
<p class="help">Prospective customers</p>
|
||||
<br>
|
||||
<h4><a href="#!List/Opportunity">Opportunity</a></h4>
|
||||
<p class="help">Business opportunities</p>
|
||||
<br>
|
||||
<h4><a href="#!List/Quotation">Quotation</a></h4>
|
||||
<p class="help">Quotes sent to Leads / Customers</p>
|
||||
<br>
|
||||
<h4><a href="#!List/Sales Order">Sales Order</a></h4>
|
||||
<p class="help">Confirmed orders from Customers</p>
|
||||
</div>
|
||||
<div style="width: 48%; float: right;">
|
||||
<h4><a href="#!List/Customer">Customer</a></h4>
|
||||
<p class="help">Customer Master</p>
|
||||
<br>
|
||||
<h4><a href="#!List/Item">Item</a></h4>
|
||||
<p class="help">Item Master</p>
|
||||
<br>
|
||||
<h4><a href="#!List/Contact">Contact</a></h4>
|
||||
<p class="help">Contact Master</p>
|
||||
<br>
|
||||
<h4><a href="#!List/Address">Address</a></h4>
|
||||
<p class="help">Address Master</p>
|
||||
<br>
|
||||
<h4><a href="#sales-analytics" data-role="Analytics">Sales Analytics</a>
|
||||
<span style="background-color: #fed; font-weight: normal; font-size: 80%">beta</span>
|
||||
</h4>
|
||||
<p class="help">Sales trends based on Sales Invoice</p>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
<hr>
|
||||
<h3>Reports</h3>
|
||||
<div class="reports-list"></div>
|
||||
</div>
|
||||
<div class="layout-side-section">
|
||||
<div class="psidebar">
|
||||
<div class="section">
|
||||
<div class="section-head">Setup</div>
|
||||
<div class="section-body">
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Tax and charges structure master"
|
||||
href="#!List/Sales Taxes and Charges Master">Sales Taxes and Charges Master</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Multiple prices lists for items"
|
||||
href="#!List/Price List">Price List</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Group items and accessories in one item code"
|
||||
href="#!List/Sales BOM">Sales BOM</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Terms of contract template"
|
||||
href="#!List/Terms and Conditions">Terms and Conditions Template</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Tree of customer groups"
|
||||
href="#!Sales Browser/Customer Group">Customer Group</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Tree of sales territories"
|
||||
href="#!Sales Browser/Territory">Territory</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Sales persons and targets"
|
||||
href="#!Sales Browser/Sales Person">Sales Person</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Commission partners and targets"
|
||||
href="#!List/Sales Partner">Sales Partner</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Tree of item classification"
|
||||
href="#!Sales Browser/Item Group">Item Group</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Sales campaigns"
|
||||
href="#!List/Campaign">Campaign</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Send mass SMS to your contacts, leads and employees"
|
||||
href="#!Form/SMS Center/SMS Center">SMS Center</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="section-head">Tools</div>
|
||||
<div class="section-body">
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Helper for managing return of goods (sales or purchase)"
|
||||
href="#!Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool">Sales Returns</a>
|
||||
</div>
|
||||
<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "Analyze Sales and Purchase trends and slice them based on item, customer, groups etc"
|
||||
href="#!Report/Profile/Trend Analyzer">Trend Analyzer</a>
|
||||
</div>
|
||||
<!--<div class="section-item">
|
||||
<a class="section-link"
|
||||
title = "sales trends"
|
||||
href="#!Sales Dashboard">Sales Dashboard</a>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
20
selling/page/selling_home/selling_home.js
Normal file
20
selling/page/selling_home/selling_home.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pscript['onload_selling-home'] = function(wrapper) {
|
||||
wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'), 'Selling');
|
||||
erpnext.module_page.setup_page('Selling', wrapper);
|
||||
}
|
||||
43
selling/page/selling_home/selling_home.txt
Normal file
43
selling/page/selling_home/selling_home.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
# Page, selling-home
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-02-20 15:46:39',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-02-20 15:46:57',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Page
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'page_name': u'selling-home',
|
||||
'standard': u'Yes',
|
||||
'title': u'Selling Home'
|
||||
},
|
||||
|
||||
# These values are common for all Page Role
|
||||
{
|
||||
'doctype': u'Page Role',
|
||||
'name': '__common__',
|
||||
'parent': u'selling-home',
|
||||
'parentfield': u'roles',
|
||||
'parenttype': u'Page',
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# Page, selling-home
|
||||
{
|
||||
'doctype': 'Page',
|
||||
'name': u'selling-home'
|
||||
},
|
||||
|
||||
# Page Role
|
||||
{
|
||||
'doctype': u'Page Role'
|
||||
}
|
||||
]
|
||||
1
selling/search_criteria/__init__.py
Normal file
1
selling/search_criteria/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,23 @@
|
||||
from __future__ import unicode_literals
|
||||
col_defs = [
|
||||
{'label': 'Id', 'type': 'Link', 'width': '', 'options': 'Customer'},
|
||||
{'label': 'Customer Name'},
|
||||
{'label': 'Address Line 1', 'width': '200px'},
|
||||
{'label': 'Address Line 2', 'width': '200px'},
|
||||
{'label': 'City'},
|
||||
{'label': 'State'},
|
||||
{'label': 'Pincode', 'width': '80px'},
|
||||
{'label': 'Country', 'width': '100px'},
|
||||
{'label': 'Contact First Name'},
|
||||
{'label': 'Contact Last Name'},
|
||||
{'label': 'Contact Phone', 'width': '100px'},
|
||||
{'label': 'Contact Mobile', 'width': '100px'},
|
||||
{'label': 'Contact Email'},
|
||||
]
|
||||
webnotes.msgprint(colnames)
|
||||
for col in col_defs:
|
||||
colnames.append(col['label'])
|
||||
coltypes.append(col.get('type') or 'Data')
|
||||
colwidths.append(col.get('width') or '150px')
|
||||
coloptions.append(col.get('options') or '')
|
||||
col_idx[col['label']] = len(colnames) - 1
|
||||
@@ -0,0 +1,26 @@
|
||||
select
|
||||
`tabCustomer`.name,
|
||||
`tabCustomer`.customer_name,
|
||||
`tabAddress`.address_line1,
|
||||
`tabAddress`.address_line2,
|
||||
`tabAddress`.city,
|
||||
`tabAddress`.state,
|
||||
`tabAddress`.pincode,
|
||||
`tabAddress`.country,
|
||||
`tabContact`.first_name,
|
||||
`tabContact`.last_name,
|
||||
`tabContact`.phone,
|
||||
`tabContact`.mobile_no,
|
||||
`tabContact`.email_id
|
||||
from
|
||||
`tabCustomer`
|
||||
left join `tabAddress` on (
|
||||
`tabAddress`.customer=`tabCustomer`.name and
|
||||
ifnull(`tabAddress`.is_primary_address, 0)=1
|
||||
)
|
||||
left join `tabContact` on (
|
||||
`tabContact`.customer=`tabCustomer`.name and
|
||||
ifnull(`tabContact`.is_primary_contact, 0)=1
|
||||
)
|
||||
order by
|
||||
`tabCustomer`.customer_name asc
|
||||
@@ -0,0 +1,31 @@
|
||||
# Search Criteria, customer_address_contact
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-04-17 11:29:10',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-23 18:17:40',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Search Criteria
|
||||
{
|
||||
'columns': u'Customer\x01ID,Customer\x01Customer Name',
|
||||
'criteria_name': u'Customer Address Contact',
|
||||
'doc_type': u'Customer',
|
||||
'doctype': 'Search Criteria',
|
||||
'filters': u"{'Customer\x01Saved':1,'Customer\x01Submitted':1}",
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'page_len': 50,
|
||||
'standard': u'Yes'
|
||||
},
|
||||
|
||||
# Search Criteria, customer_address_contact
|
||||
{
|
||||
'doctype': 'Search Criteria',
|
||||
'name': u'customer_address_contact'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,20 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
report.customize_filters = function() {
|
||||
this.filter_fields_dict['Delivery Note'+FILTER_SEP +'Company'].df['report_default'] = sys_defaults.company;
|
||||
this.filter_fields_dict['Delivery Note'+FILTER_SEP +'Fiscal Year'].df['report_default'] = sys_defaults.fiscal_year;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Search Criteria, delivered_items_to_be_install
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-04-03 12:49:51',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-04-03 12:49:51',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Search Criteria
|
||||
{
|
||||
'add_col': u"(`tabDelivery Note Item`.`qty`- ifnull(`tabDelivery Note Item`.`installed_qty`, 0)) AS 'Pending to Install'",
|
||||
'add_cond': u'`tabDelivery Note Item`.`qty` > ifnull(`tabDelivery Note Item`.`installed_qty`, 0)',
|
||||
'columns': u'Delivery Note\x01ID,Delivery Note\x01Status,Delivery Note\x01Customer,Delivery Note\x01Customer Name,Delivery Note\x01Contact Person,Delivery Note\x01Voucher Date,Delivery Note Item\x01Item Code,Delivery Note Item\x01Item Name,Delivery Note Item\x01Quantity,Delivery Note Item\x01Installed Qty,Delivery Note\x01% Installed',
|
||||
'criteria_name': u'Delivered Items to be Install',
|
||||
'description': u'Delivered Items to be Install',
|
||||
'doc_type': u'Delivery Note Item',
|
||||
'doctype': 'Search Criteria',
|
||||
'filters': u"{'Delivery Note\x01Saved':1,'Delivery Note\x01Submitted':1,'Delivery Note\x01Status':'','Delivery Note\x01Fiscal Year':''}",
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'page_len': 50,
|
||||
'parent_doc_type': u'Delivery Note',
|
||||
'sort_by': u'`tabDelivery Note`.`name`',
|
||||
'sort_order': u'DESC',
|
||||
'standard': u'Yes'
|
||||
},
|
||||
|
||||
# Search Criteria, delivered_items_to_be_install
|
||||
{
|
||||
'doctype': 'Search Criteria',
|
||||
'name': u'delivered_items_to_be_install'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,37 @@
|
||||
# Search Criteria, delivery_note_itemwise_pending_to_bill
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-04-03 12:49:51',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-04-03 12:49:51',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'jai@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all Search Criteria
|
||||
{
|
||||
'add_col': u"SUM(`tabDelivery Note Item`.`qty` - `tabDelivery Note Item`.`billed_qty`) AS 'Pending Qty'\nSUM((`tabDelivery Note Item`.`qty` - `tabDelivery Note Item`.`billed_qty`) * `tabDelivery Note Item`.`basic_rate`) AS 'Pending Amount'",
|
||||
'add_cond': u"`tabDelivery Note`.status != 'Stopped'\nCASE WHEN `tabDelivery Note`.`per_billed` IS NULL OR `tabDelivery Note`.per_billed = '' THEN 0 < 100 ELSE `tabDelivery Note`.per_billed <100 END",
|
||||
'columns': u'Delivery Note\x01ID,Delivery Note\x01Owner,Delivery Note\x01Status,Delivery Note\x01Customer Name,Delivery Note\x01Voucher Date,Delivery Note\x01% Billed,Delivery Note\x01Posting Date,Delivery Note\x01Company Name,Delivery Note\x01Fiscal Year,Delivery Note Item\x01Item Code,Delivery Note Item\x01Against Document No,Delivery Note Item\x01Document Type,Delivery Note Item\x01Against Document Detail No',
|
||||
'criteria_name': u'Delivery Note Itemwise Pending To Bill',
|
||||
'doc_type': u'Delivery Note Item',
|
||||
'doctype': 'Search Criteria',
|
||||
'filters': u"{'Delivery Note\x01Saved':1,'Delivery Note\x01Submitted':1,'Delivery Note\x01Status':'','Delivery Note\x01Company Name':'','Delivery Note\x01Fiscal Year':''}",
|
||||
'group_by': u'`tabDelivery Note Item`.item_code, `tabDelivery Note`.`name`',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'page_len': 50,
|
||||
'parent_doc_type': u'Delivery Note',
|
||||
'sort_by': u'`tabDelivery Note`.`name`',
|
||||
'sort_order': u'DESC',
|
||||
'standard': u'Yes'
|
||||
},
|
||||
|
||||
# Search Criteria, delivery_note_itemwise_pending_to_bill
|
||||
{
|
||||
'doctype': 'Search Criteria',
|
||||
'name': u'delivery_note_itemwise_pending_to_bill'
|
||||
}
|
||||
]
|
||||
1
selling/search_criteria/draft_sales_orders/__init__.py
Normal file
1
selling/search_criteria/draft_sales_orders/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user