mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-13 02:01:21 +00:00
moved directory structure
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# DocType Mapper, Delivery Note-Packing Slip
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-02-22 15:45:56',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-02-22 15:45:56',
|
||||
'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'Delivery Note-Packing Slip',
|
||||
'parentfield': u'table_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': u'Delivery Note-Packing Slip',
|
||||
'parentfield': u'field_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': u'Delivery Note',
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'ref_doc_submitted': 0,
|
||||
'to_doctype': u'Packing Slip'
|
||||
},
|
||||
|
||||
# DocType Mapper, Delivery Note-Packing Slip
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': u'Delivery Note-Packing Slip'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'name',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'delivery_note'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'qty',
|
||||
'map': u'No',
|
||||
'match_id': 1,
|
||||
'to_field': u'qty'
|
||||
},
|
||||
|
||||
# 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'Delivery Note',
|
||||
'match_id': 0,
|
||||
'to_table': u'Packing Slip',
|
||||
'validation_logic': u'docstatus=0'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'delivery_note_details',
|
||||
'from_table': u'Delivery Note Item',
|
||||
'match_id': 1,
|
||||
'to_field': u'item_details',
|
||||
'to_table': u'Packing Slip Item',
|
||||
'validation_logic': u'IFNULL(packed_qty, 0) < IFNULL(qty, 0)'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,64 @@
|
||||
# DocType Mapper, Project-Delivery Note
|
||||
[
|
||||
|
||||
# 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': 'harshada@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-Delivery Note',
|
||||
'parentfield': 'table_mapper_details',
|
||||
'parenttype': 'DocType Mapper',
|
||||
'to_table': 'Delivery Note',
|
||||
'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-Delivery Note',
|
||||
'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': 'Stock',
|
||||
'name': '__common__',
|
||||
'to_doctype': 'Delivery Note'
|
||||
},
|
||||
|
||||
# DocType Mapper, Project-Delivery Note
|
||||
{
|
||||
'doctype': 'DocType Mapper',
|
||||
'name': 'Project-Delivery Note'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': 'Field Mapper Detail'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': 'Table Mapper Detail'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,245 @@
|
||||
# DocType Mapper, Purchase Order-Purchase Receipt
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:35',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-04-02 14:03:39',
|
||||
'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'Purchase Order-Purchase Receipt',
|
||||
'parentfield': u'table_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'map': u'Yes',
|
||||
'name': '__common__',
|
||||
'parent': u'Purchase Order-Purchase Receipt',
|
||||
'parentfield': u'field_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': u'Purchase Order',
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'ref_doc_submitted': 1,
|
||||
'to_doctype': u'Purchase Receipt'
|
||||
},
|
||||
|
||||
# DocType Mapper, Purchase Order-Purchase Receipt
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': u'Purchase Order-Purchase Receipt'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'supplier',
|
||||
'match_id': 0,
|
||||
'to_field': u'supplier'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'company',
|
||||
'match_id': 0,
|
||||
'to_field': u'company'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'currency',
|
||||
'match_id': 0,
|
||||
'to_field': u'currency'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'name',
|
||||
'match_id': 1,
|
||||
'to_field': u'prevdoc_detail_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'parent',
|
||||
'match_id': 1,
|
||||
'to_field': u'prevdoc_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'parenttype',
|
||||
'match_id': 1,
|
||||
'to_field': u'prevdoc_doctype'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'item_code',
|
||||
'match_id': 1,
|
||||
'to_field': u'item_code'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval:(flt(obj.qty) - flt(obj.received_qty)) ',
|
||||
'match_id': 1,
|
||||
'to_field': u'received_qty'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval:(flt(obj.qty) - flt(obj.received_qty)) ',
|
||||
'match_id': 1,
|
||||
'to_field': u'qty'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)',
|
||||
'match_id': 1,
|
||||
'to_field': u'stock_qty'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.import_rate)',
|
||||
'match_id': 1,
|
||||
'to_field': u'import_amount'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.purchase_rate)',
|
||||
'match_id': 1,
|
||||
'to_field': u'amount'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'schedule_date',
|
||||
'match_id': 1,
|
||||
'to_field': u'schedule_date'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'net_total',
|
||||
'match_id': 0,
|
||||
'to_field': u'net_total'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'grand_total',
|
||||
'match_id': 0,
|
||||
'to_field': u'grand_total'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'total_tax',
|
||||
'match_id': 0,
|
||||
'to_field': u'total_tax'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'conversion_rate',
|
||||
'match_id': 0,
|
||||
'to_field': u'conversion_rate'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'po_details',
|
||||
'from_table': u'Purchase Order Item',
|
||||
'match_id': 1,
|
||||
'reference_doctype_key': u'prevdoc_doctype',
|
||||
'reference_key': u'prevdoc_detail_docname',
|
||||
'to_field': u'purchase_receipt_details',
|
||||
'to_table': u'Purchase Receipt Item',
|
||||
'validation_logic': u'docstatus=1 and qty > ifnull(received_qty,0)'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'po_details',
|
||||
'from_table': u'Purchase Order Item',
|
||||
'match_id': 1,
|
||||
'reference_doctype_key': u'prevdoc_doctype',
|
||||
'reference_key': u'prevdoc_detail_docname',
|
||||
'to_field': u'purchase_receipt_details',
|
||||
'to_table': u'Purchase Receipt Item',
|
||||
'validation_logic': u'docstatus=1 and qty > ifnull(received_qty,0)'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_table': u'Purchase Order',
|
||||
'match_id': 0,
|
||||
'reference_key': u'prevdoc_docname',
|
||||
'to_table': u'Purchase Receipt',
|
||||
'validation_logic': u'docstatus = 1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'purchase_tax_details',
|
||||
'from_table': u'Purchase Taxes and Charges',
|
||||
'match_id': 2,
|
||||
'to_field': u'purchase_tax_details',
|
||||
'to_table': u'Purchase Taxes and Charges',
|
||||
'validation_logic': u'docstatus = 1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'purchase_tax_details',
|
||||
'from_table': u'Purchase Taxes and Charges',
|
||||
'match_id': 2,
|
||||
'to_field': u'purchase_tax_details',
|
||||
'to_table': u'Purchase Taxes and Charges',
|
||||
'validation_logic': u'docstatus = 1'
|
||||
}
|
||||
]
|
||||
169
stock/DocType Mapper/Sales Invoice-Delivery Note/Sales Invoice-Delivery Note.txt
Executable file
169
stock/DocType Mapper/Sales Invoice-Delivery Note/Sales Invoice-Delivery Note.txt
Executable file
@@ -0,0 +1,169 @@
|
||||
# DocType Mapper, Sales Invoice-Delivery Note
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-12-14 17:56:41',
|
||||
'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'Sales Invoice-Delivery Note',
|
||||
'parentfield': u'table_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales Invoice-Delivery Note',
|
||||
'parentfield': u'field_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': u'Sales Invoice',
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'ref_doc_submitted': 1,
|
||||
'to_doctype': u'Delivery Note'
|
||||
},
|
||||
|
||||
# DocType Mapper, Sales Invoice-Delivery Note
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': u'Sales Invoice-Delivery Note'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval: flt(obj.qty) - flt(obj.delivered_qty)',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'qty'
|
||||
},
|
||||
|
||||
# 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'name',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'prevdoc_detail_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval: (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.basic_rate)',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'amount'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval: (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.export_rate)',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'export_amount'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'naming_series',
|
||||
'map': u'No',
|
||||
'match_id': 0,
|
||||
'to_field': u'naming_series'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'customer_address',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'delivery_address'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'serial_no',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'serial_no'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_table': u'Sales Invoice',
|
||||
'match_id': 0,
|
||||
'to_table': u'Delivery Note',
|
||||
'validation_logic': u'docstatus=1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'entries',
|
||||
'from_table': u'Sales Invoice Item',
|
||||
'match_id': 1,
|
||||
'to_field': u'delivery_note_details',
|
||||
'to_table': u'Delivery Note Item',
|
||||
'validation_logic': u'docstatus = 1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'other_charges',
|
||||
'from_table': u'Sales Taxes and Charges',
|
||||
'match_id': 2,
|
||||
'to_field': u'other_charges',
|
||||
'to_table': u'Sales Taxes and Charges',
|
||||
'validation_logic': u'name is not null'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'sales_team',
|
||||
'from_table': u'Sales Team',
|
||||
'match_id': 3,
|
||||
'to_field': u'sales_team',
|
||||
'to_table': u'Sales Team',
|
||||
'validation_logic': u'name is not null'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,258 @@
|
||||
# DocType Mapper, Sales Order-Delivery Note
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:35',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-08 11:50:18',
|
||||
'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'Sales Order-Delivery Note',
|
||||
'parentfield': u'table_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales Order-Delivery Note',
|
||||
'parentfield': u'field_mapper_details',
|
||||
'parenttype': u'DocType Mapper'
|
||||
},
|
||||
|
||||
# These values are common for all DocType Mapper
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'from_doctype': u'Sales Order',
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'ref_doc_submitted': 1,
|
||||
'to_doctype': u'Delivery Note'
|
||||
},
|
||||
|
||||
# DocType Mapper, Sales Order-Delivery Note
|
||||
{
|
||||
'doctype': u'DocType Mapper',
|
||||
'name': u'Sales Order-Delivery Note'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'name',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'sales_order_no'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'company',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'company'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'currency',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'currency'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'shipping_address_name',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'customer_address'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'shipping_address',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'address_display'
|
||||
},
|
||||
|
||||
# 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'name',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'prevdoc_detail_docname'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval: (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.export_rate)',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'export_amount'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'export_rate',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'export_rate'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval: flt(obj.qty) - flt(obj.delivered_qty)',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'qty'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'eval: (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.basic_rate)',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'amount'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'reserved_warehouse',
|
||||
'map': u'Yes',
|
||||
'match_id': 1,
|
||||
'to_field': u'warehouse'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'project_name',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'project_name'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'checking_operator': u'=',
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'customer',
|
||||
'map': u'Yes',
|
||||
'match_id': 0,
|
||||
'to_field': u'customer'
|
||||
},
|
||||
|
||||
# Field Mapper Detail
|
||||
{
|
||||
'doctype': u'Field Mapper Detail',
|
||||
'from_field': u'naming_series',
|
||||
'map': u'No',
|
||||
'match_id': 0,
|
||||
'to_field': u'naming_series'
|
||||
},
|
||||
|
||||
# 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'incentives',
|
||||
'map': u'No',
|
||||
'match_id': 3,
|
||||
'to_field': u'incentives'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'sales_team',
|
||||
'from_table': u'Sales Team',
|
||||
'match_id': 3,
|
||||
'to_field': u'sales_team',
|
||||
'to_table': u'Sales Team',
|
||||
'validation_logic': u'name is not null'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'other_charges',
|
||||
'from_table': u'Sales Taxes and Charges',
|
||||
'match_id': 2,
|
||||
'to_field': u'other_charges',
|
||||
'to_table': u'Sales Taxes and Charges',
|
||||
'validation_logic': u'name is not null'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_field': u'sales_order_details',
|
||||
'from_table': u'Sales Order Item',
|
||||
'match_id': 1,
|
||||
'reference_doctype_key': u'prevdoc_doctype',
|
||||
'reference_key': u'prevdoc_detail_docname',
|
||||
'to_field': u'delivery_note_details',
|
||||
'to_table': u'Delivery Note Item',
|
||||
'validation_logic': u'qty > ifnull(delivered_qty,0) and docstatus = 1'
|
||||
},
|
||||
|
||||
# Table Mapper Detail
|
||||
{
|
||||
'doctype': u'Table Mapper Detail',
|
||||
'from_table': u'Sales Order',
|
||||
'match_id': 0,
|
||||
'reference_key': u'prevdoc_docname',
|
||||
'to_table': u'Delivery Note',
|
||||
'validation_logic': u'docstatus = 1'
|
||||
}
|
||||
]
|
||||
1
stock/Item Group/All Item Groups/All Item Groups.txt
Normal file
1
stock/Item Group/All Item Groups/All Item Groups.txt
Normal file
@@ -0,0 +1 @@
|
||||
[{'creation': '2010-07-16 11:03:21', 'doctype': 'Item Group', 'lft': 1, 'owner': 'harshada@webnotestech.com', 'rgt': 286, 'company_abbr': None, 'docstatus': 0, 'item_group_name': 'All Item Groups', 'description': None, 'parent': None, 'is_group': 'Yes', 'company': None, 'show_in_catalogue': None, 'group_or_ledger': None, 'modified_by': 'harshada@webnotestech.com', 'group_name': None, 'trash_reason': None, 'name': 'All Item Groups', 'idx': None, 'modified': '2010-07-16 11:03:21', 'parent_item_group': '', 'old_parent': '', 'parenttype': None, 'parentfield': None}]
|
||||
1
stock/Item Group/Default/Default.txt
Normal file
1
stock/Item Group/Default/Default.txt
Normal file
@@ -0,0 +1 @@
|
||||
[{'creation': '2010-07-05 16:08:14', 'doctype': 'Item Group', 'lft': 76, 'owner': 'nabin@webnotestech.com', 'rgt': 77, 'company_abbr': None, 'docstatus': 0, 'item_group_name': 'Default', 'description': None, 'parent': None, 'is_group': 'No', 'company': None, 'show_in_catalogue': None, 'group_or_ledger': None, 'modified_by': 'nabin@webnotestech.com', 'group_name': None, 'trash_reason': None, 'name': 'Default', 'idx': None, 'modified': '2010-07-05 16:08:14', 'parent_item_group': 'All Item Groups', 'old_parent': '', 'parenttype': None, 'parentfield': None}]
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,27 @@
|
||||
# Print Format, Delivery Note Packing List Wise
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2011-08-23 16:49:40',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-10-19 14:12:11',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Print Format
|
||||
{
|
||||
'doctype': 'Print Format',
|
||||
'html': "<html>\n<head>\n\n<script>\nfunction replaceAll(s,s1,s2){ return s.split(s1).join(s2);}\n\nfunction get_letter_head() {\n\t// add letter head\n\tvar cp = locals['Control Panel']['Control Panel'];\n\tif(doc.letter_head)\n\t\tvar lh= cstr(_p.letter_heads[doc.letter_head]);\n\telse if(cp.letter_head)\n\t\tvar lh= cp.letter_head;\n\telse \n\t\tvar lh= '';\n\t\t\n\treturn lh;\n}\n\n</script>\n<style>\n.cust_tbl { border-collapse:collapse; }\n.cust_tbl td { border:1px solid #848484; font-size: 13px}\n.large_font td {font-size: 13px}\n</style>\n</head>\n\n<body>\n<script>\nreplaceAll(doc.print_packing_slip,'[HEADER GOES HERE]',get_letter_head());\n</script>\n</body>\n</html>",
|
||||
'module': 'Stock',
|
||||
'name': '__common__',
|
||||
'standard': 'Yes'
|
||||
},
|
||||
|
||||
# Print Format, Delivery Note Packing List Wise
|
||||
{
|
||||
'doctype': 'Print Format',
|
||||
'name': 'Delivery Note Packing List Wise'
|
||||
}
|
||||
]
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,27 @@
|
||||
# Print Format, Purchase Receipt Format
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2010-08-08 17:09:34',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-10-19 14:18:26',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all Print Format
|
||||
{
|
||||
'doctype': 'Print Format',
|
||||
'html': '<html>\n<head>\n<!--Other charges function-->\n<script>\n var make_row = function(title,val,bold){\n var bstart = \'<b>\'; var bend = \'</b>\';\n return \'<tr><td style="width:50%">\'+(bold?bstart:\'\')+title+(bold?bend:\'\')+\'</td>\'\n +\'<td style="width:20%;text-align:right">\'+doc.currency+\'</td>\'\n +\'<td style="width:30%;text-align:right">\'+(val?val:\'0.00\')+\'</td>\'\n +\'</tr>\'\n }\n\n function get_other_charges(){\n var out =\'\';\n out += \'<div><table class="noborder" style="width:100%">\';\n out += make_row(\'Total Amount\',fmt_money(convert_rate(doc.total_amount)),1)\n +make_row(\'Grand Total\',fmt_money(convert_rate(doc.grand_total)),1);\n out += \'</table></div>\';\n return out;\n }\n\n function get_buying_costs(){\n var out =\'\';\n if(doc.buying_cost_transport || doc.buying_cost_taxes || doc.buying_cost_other){\n out += \'<div><table class="noborder" style="width:100%">\'\n + \'<tr><td style="width:100%"><b>\'+\'Buying Cost Details\'+\'</b></td></tr>\';\n if(doc.buying_cost_transport){ out += make_row(\'Transport Cost\',fmt_money(convert_rate(doc.buying_cost_transport)),0)}\n if(doc.buying_cost_taxes){ out += make_row(\'Taxes\',fmt_money(convert_rate(doc.buying_cost_taxes)),0)}\n if(doc.buying_cost_other){ out += make_row(\'Other Cost\',fmt_money(convert_rate(doc.buying_cost_other)),0)}\n out += \'</table></div>\';\n }\n return out;\n }\n\nfunction get_letter_head() {\n\t// add letter head\n\tvar cp = locals[\'Control Panel\'][\'Control Panel\'];\n\tif(doc.letter_head)\n\t\tvar lh= cstr(_p.letter_heads[doc.letter_head]);\n\telse if(cp.letter_head)\n\t\tvar lh= cp.letter_head;\n\telse \n\t\tvar lh= \'\';\n\t\t\n\treturn lh;\n}\n\n \n function convert_rate(val){\n var new_val = flt(val)/flt(doc.conversion_rate);\n return new_val;\n }\n \n function get_transport_details(){\n var out = \'\';\n if(doc.transporter_name || doc.lr_no || doc.lr_date){\n out += \'<div><table class="noborder" style="width:40%">\'\n +\'<tr><td style="width:80%"><b>\' + \'Transporter Details\'+\'</b></td><td style="width:20%"></td></tr>\'\n\n if(doc.transporter_name){ out += \'<tr><td style="width:40%">\' + \'Transporter Name\'+\'</td><td style="width:60%">\'+doc.transporter_name+\'</td></tr>\'}\n if(doc.lr_no){ out += \'<tr><td style="width:40%">\' + \'LR No\'+\'</td><td style="width:60%">\'+doc.lr_no+\'</td></tr>\'}\n if(doc.lr_date){ out += \'<tr><td style="width:40%">\' + \'LR Date\'+\'</td><td style="width:60%">\'+doc.lr_date+\'</td></tr>\'}\n out += \'</table></div>\'\n }\n return out;\n }\n\n</script>\n</head>\n<body>\n<div style="border:1px solid black;padding:15px">\n<!--header-->\n<div><script>get_letter_head()</script></div>\n<div style="border-bottom: 1px solid; padding-bottom: 5px;">\n <div><br><b>Purchase Receipt: <script>doc.name</script></b></div>\n <div>Date: <script>date.str_to_user(doc.transaction_date)</script></div>\n</div>\n\n<div style="padding-top:15px">\n<div><script>doc.supplier</script></div>\n<div><br><script>replace_newlines(doc.address_display)</script></div>\n</div>\n\n<div>\n<br>\n <script>\n var t = print_table(\'Purchase Receipt\', doc.name, \'purchase_receipt_details\', \'Purchase Receipt Item\', [\'SR\', \'item_code\',\'description\',\'received_qty\',\'qty\',\'rejected_qty\',\'po_rate\',\'amount\',\'billed_qty\'], [\'Sr\', \'Item Code\', \'Description\',\'Received Quantity\',\'Accepted Qty\',\'Rejected Qty\',\'Rate\',\'Amount\',\'Billed Qty\'], [\'4%\',\'12%\', \'24%\', \'10%\',\'10%\',\'10%\',\'10%\',\'10%\',\'10%\'])\n if(t.appendChild) {\n // single\n out = t.innerHTML;\n } \n else {//multiple\n out = \'\'\n for(var i=0;i<t.length;i++) {\n if(i!=t.length-1){\n out += \'<div style:"padding-top:5px;"></div>\' + t[i].innerHTML +\'<div style="page-break-after:always"></div>\';\n }\n else out += \'<div style:"padding-top:5px;"></div>\' + t[i].innerHTML;\n }\n }\n out;\n </script>\n\n</div>\n\n<!--Other charges table-->\n<div>\n<table style="width:100%">\n <tr><td style="width:40%"><script>get_buying_costs()</script></td>\n <td style="width:20%"></td><td style="width:40%"><script>get_other_charges()</script></td></tr>\n</table>\n</div>\n<div><script>get_transport_details()</script></div>\n<div><br>Payment Terms</div>\n<div><br><script>replace_newlines(doc.payment_terms)</script></div>\n<div><br>For NCSCI</div>\n<div><br><br>(Authorised Signatory)</div>\n</div></body>\n</html>',
|
||||
'module': 'Stock',
|
||||
'name': '__common__',
|
||||
'standard': 'Yes'
|
||||
},
|
||||
|
||||
# Print Format, Purchase Receipt Format
|
||||
{
|
||||
'doctype': 'Print Format',
|
||||
'name': 'Purchase Receipt Format'
|
||||
}
|
||||
]
|
||||
7
stock/__init__.py
Normal file
7
stock/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
install_docs = [
|
||||
{"doctype":"Role", "role_name":"Material Manager", "name":"Material Manager"},
|
||||
{"doctype":"Role", "role_name":"Material Master Manager", "name":"Material Master Manager"},
|
||||
{"doctype":"Role", "role_name":"Material User", "name":"Material User"},
|
||||
{"doctype":"Role", "role_name":"Quality Manager", "name":"Quality Manager"},
|
||||
]
|
||||
1
stock/doctype/__init__.py
Normal file
1
stock/doctype/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
1
stock/doctype/batch/__init__.py
Normal file
1
stock/doctype/batch/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
149
stock/doctype/batch/batch.txt
Normal file
149
stock/doctype/batch/batch.txt
Normal file
@@ -0,0 +1,149 @@
|
||||
# DocType, Batch
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:26',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:26',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'harshada@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'allow_trash': 1,
|
||||
'autoname': u'field:batch_id',
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 12
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Batch',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Batch',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1,
|
||||
'role': u'Material Master Manager'
|
||||
},
|
||||
|
||||
# DocType, Batch
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Batch'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 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'batch_id',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Batch ID',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'batch_id',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'start_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Batch Started Date',
|
||||
'oldfieldname': u'start_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'finished_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Batch Finished Date',
|
||||
'oldfieldname': u'finished_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'expiry_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Expiry Date',
|
||||
'oldfieldname': u'expiry_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item',
|
||||
'oldfieldname': u'item',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
}
|
||||
]
|
||||
28
stock/doctype/batch/batch_list.js
Normal file
28
stock/doctype/batch/batch_list.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// render
|
||||
wn.doclistviews['Batch'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabBatch`.item",
|
||||
"`tabBatch`.description",
|
||||
]);
|
||||
this.stats = this.stats.concat(['company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(data.description && data.description.length > 50) {
|
||||
data.description = '<span title="'+data.description+'">' +
|
||||
data.description.substr(0,50) + '...</span>';
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content:'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '15%', content:'item'},
|
||||
{width: '50%', content:'description+tags'},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
||||
]
|
||||
});
|
||||
1
stock/doctype/bin/__init__.py
Normal file
1
stock/doctype/bin/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
405
stock/doctype/bin/bin.py
Normal file
405
stock/doctype/bin/bin.py
Normal file
@@ -0,0 +1,405 @@
|
||||
# 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, 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
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
# -------------
|
||||
# stock update
|
||||
# -------------
|
||||
def update_stock(self, actual_qty=0, reserved_qty=0, ordered_qty=0, indented_qty=0, planned_qty=0, dt=None, sle_id='', posting_time='', serial_no = '', is_cancelled = 'No',doc_type='',doc_name='',is_amended='No'):
|
||||
if not dt:
|
||||
dt = nowdate()
|
||||
|
||||
# update the stock values (for current quantities)
|
||||
self.doc.actual_qty = flt(self.doc.actual_qty) + flt(actual_qty)
|
||||
self.doc.ordered_qty = flt(self.doc.ordered_qty) + flt(ordered_qty)
|
||||
self.doc.reserved_qty = flt(self.doc.reserved_qty) + flt(reserved_qty)
|
||||
self.doc.indented_qty = flt(self.doc.indented_qty) + flt(indented_qty)
|
||||
self.doc.planned_qty = flt(self.doc.planned_qty) + flt(planned_qty)
|
||||
self.doc.projected_qty = flt(self.doc.actual_qty) + flt(self.doc.ordered_qty) + flt(self.doc.indented_qty) + flt(self.doc.planned_qty) - flt(self.doc.reserved_qty)
|
||||
self.doc.save()
|
||||
if(( flt(actual_qty)<0 or flt(reserved_qty)>0 ) and is_cancelled == 'No' and is_amended=='No'):
|
||||
self.reorder_item(doc_type,doc_name)
|
||||
|
||||
if actual_qty:
|
||||
# check actual qty with total number of serial no
|
||||
if serial_no:
|
||||
self.check_qty_with_serial_no()
|
||||
|
||||
# update valuation and qty after transaction for post dated entry
|
||||
self.update_entries_after(dt, posting_time)
|
||||
|
||||
def check_qty_with_serial_no(self):
|
||||
"""
|
||||
check actual qty with total number of serial no in store
|
||||
Temporary validation added on: 18-07-2011
|
||||
"""
|
||||
if sql("select name from `tabItem` where ifnull(has_serial_no, 'No') = 'Yes' and name = '%s'" % self.doc.item_code):
|
||||
sr_count = sql("""select count(name) from `tabSerial No`
|
||||
where item_code = '%s' and warehouse = '%s'
|
||||
and status ='In Store' and docstatus != 2
|
||||
""" % (self.doc.item_code, self.doc.warehouse))[0][0]
|
||||
|
||||
if sr_count != self.doc.actual_qty:
|
||||
msg = """Actual Qty(%s) in Bin is mismatched with total number(%s) of serial no in store
|
||||
for item: '%s' and warehouse: '%s'""" % \
|
||||
(self.doc.actual_qty, sr_count, self.doc.item_code, self.doc.warehouse)
|
||||
|
||||
msgprint(msg, raise_exception=1)
|
||||
|
||||
# --------------------------------
|
||||
# get first stock ledger entry
|
||||
# --------------------------------
|
||||
|
||||
def get_first_sle(self):
|
||||
sle = sql("""
|
||||
select * from `tabStock Ledger Entry`
|
||||
where item_code = %s
|
||||
and warehouse = %s
|
||||
and ifnull(is_cancelled, 'No') = 'No'
|
||||
order by timestamp(posting_date, posting_time) asc, name asc
|
||||
limit 1
|
||||
""", (self.doc.item_code, self.doc.warehouse), as_dict=1)
|
||||
return sle and sle[0] or None
|
||||
|
||||
def get_prev_sle(self, posting_date = '1900-01-01', posting_time = '12:00', sle_id = ''):
|
||||
"""
|
||||
get the last sle on or before the current time-bucket,
|
||||
to get actual qty before transaction, this function
|
||||
is called from various transaction like stock entry, reco etc
|
||||
"""
|
||||
|
||||
sle = sql("""
|
||||
select * from `tabStock Ledger Entry`
|
||||
where item_code = %s
|
||||
and warehouse = %s
|
||||
and ifnull(is_cancelled, 'No') = 'No'
|
||||
and name != %s
|
||||
and timestamp(posting_date, posting_time) <= timestamp(%s, %s)
|
||||
order by timestamp(posting_date, posting_time) desc, name desc
|
||||
limit 1
|
||||
""", (self.doc.item_code, self.doc.warehouse, sle_id, posting_date, posting_time), as_dict=1)
|
||||
|
||||
return sle and sle[0] or {}
|
||||
|
||||
|
||||
def get_sle_prev_timebucket(self, posting_date = '1900-01-01', posting_time = '12:00'):
|
||||
"""get previous stock ledger entry before current time-bucket"""
|
||||
# get the last sle before the current time-bucket, so that all values
|
||||
# are reposted from the current time-bucket onwards.
|
||||
# this is necessary because at the time of cancellation, there may be
|
||||
# entries between the cancelled entries in the same time-bucket
|
||||
|
||||
sle = sql("""
|
||||
select * from `tabStock Ledger Entry`
|
||||
where item_code = %s
|
||||
and warehouse = %s
|
||||
and ifnull(is_cancelled, 'No') = 'No'
|
||||
and timestamp(posting_date, posting_time) < timestamp(%s, %s)
|
||||
order by timestamp(posting_date, posting_time) desc, name desc
|
||||
limit 1
|
||||
""", (self.doc.item_code, self.doc.warehouse, posting_date, posting_time), as_dict=1)
|
||||
|
||||
return sle and sle[0] or {}
|
||||
|
||||
|
||||
#-------------------------------------------------------------
|
||||
def validate_negative_stock(self, cqty, s):
|
||||
"""
|
||||
validate negative stock for entries current datetime onwards
|
||||
will not consider cancelled entries
|
||||
"""
|
||||
diff = cqty + s['actual_qty']
|
||||
if diff < 0 and (abs(diff) > 0.0001) and s['is_cancelled'] == 'No':
|
||||
msgprint("""
|
||||
Negative stock error:
|
||||
Cannot complete this transaction because stock will
|
||||
become negative (%s) for Item <b>%s</b> in Warehouse
|
||||
<b>%s</b> on <b>%s %s</b> in Transaction %s %s""" % \
|
||||
(str(diff), self.doc.item_code, self.doc.warehouse, \
|
||||
s['posting_date'], s['posting_time'], s['voucher_type'], s['voucher_no']), \
|
||||
raise_exception=1)
|
||||
|
||||
|
||||
# ------------------------------------
|
||||
def get_serialized_inventory_values(self, val_rate, in_rate, opening_qty, actual_qty, is_cancelled, serial_nos):
|
||||
"""
|
||||
get serialized inventory values
|
||||
"""
|
||||
if flt(in_rate) < 0: # wrong incoming rate
|
||||
in_rate = val_rate
|
||||
elif flt(in_rate) == 0: # In case of delivery/stock issue, get average purchase rate of serial nos of current entry
|
||||
in_rate = flt(sql("select ifnull(avg(purchase_rate), 0) from `tabSerial No` where name in (%s)" % (serial_nos))[0][0])
|
||||
|
||||
if in_rate and val_rate == 0: # First entry
|
||||
val_rate = in_rate
|
||||
# val_rate is same as previous entry if val_rate is negative
|
||||
# Otherwise it will be calculated as per moving average
|
||||
elif opening_qty + actual_qty > 0 and ((opening_qty * val_rate) + (actual_qty * in_rate)) > 0:
|
||||
val_rate = ((opening_qty *val_rate) + (actual_qty * in_rate)) / (opening_qty + actual_qty)
|
||||
stock_val = val_rate
|
||||
return val_rate, stock_val
|
||||
|
||||
|
||||
|
||||
# ------------------------------------
|
||||
# get moving average inventory values
|
||||
# ------------------------------------
|
||||
def get_moving_average_inventory_values(self, val_rate, in_rate, opening_qty, actual_qty, is_cancelled):
|
||||
if flt(in_rate) == 0: # In case of delivery/stock issue in_rate = 0 or wrong incoming rate
|
||||
in_rate = val_rate
|
||||
|
||||
# val_rate is same as previous entry if :
|
||||
# 1. actual qty is negative(delivery note / stock entry)
|
||||
# 2. cancelled entry
|
||||
# 3. val_rate is negative
|
||||
# Otherwise it will be calculated as per moving average
|
||||
if actual_qty > 0 and (opening_qty + actual_qty) > 0 and is_cancelled == 'No' and ((opening_qty * val_rate) + (actual_qty * in_rate)) > 0:
|
||||
opening_qty = opening_qty > 0 and opening_qty or 0
|
||||
val_rate = ((opening_qty *val_rate) + (actual_qty * in_rate)) / (opening_qty + actual_qty)
|
||||
elif (opening_qty + actual_qty) <= 0:
|
||||
val_rate = 0
|
||||
stock_val = val_rate
|
||||
return val_rate, stock_val
|
||||
|
||||
|
||||
# --------------------------
|
||||
# get fifo inventory values
|
||||
# --------------------------
|
||||
def get_fifo_inventory_values(self, in_rate, actual_qty):
|
||||
# add batch to fcfs balance
|
||||
if actual_qty > 0:
|
||||
self.fcfs_bal.append([flt(actual_qty), flt(in_rate)])
|
||||
|
||||
# remove from fcfs balance
|
||||
else:
|
||||
withdraw = flt(abs(actual_qty))
|
||||
while withdraw:
|
||||
if not self.fcfs_bal:
|
||||
break # nothing in store
|
||||
|
||||
batch = self.fcfs_bal[0]
|
||||
|
||||
if batch[0] <= withdraw:
|
||||
# not enough or exactly same qty in current batch, clear batch
|
||||
withdraw -= batch[0]
|
||||
self.fcfs_bal.pop(0)
|
||||
else:
|
||||
# all from current batch
|
||||
batch[0] -= withdraw
|
||||
withdraw = 0
|
||||
|
||||
fcfs_val = sum([flt(d[0])*flt(d[1]) for d in self.fcfs_bal])
|
||||
fcfs_qty = sum([flt(d[0]) for d in self.fcfs_bal])
|
||||
val_rate = fcfs_qty and fcfs_val / fcfs_qty or 0
|
||||
|
||||
return val_rate
|
||||
|
||||
# -------------------
|
||||
# get valuation rate
|
||||
# -------------------
|
||||
def get_valuation_rate(self, val_method, serial_nos, val_rate, in_rate, stock_val, cqty, s):
|
||||
if serial_nos:
|
||||
val_rate, stock_val = self.get_serialized_inventory_values(val_rate, in_rate, opening_qty = cqty, actual_qty = s['actual_qty'], is_cancelled = s['is_cancelled'], serial_nos = serial_nos)
|
||||
elif val_method == 'Moving Average':
|
||||
val_rate, stock_val = self.get_moving_average_inventory_values(val_rate, in_rate, opening_qty = cqty, actual_qty = s['actual_qty'], is_cancelled = s['is_cancelled'])
|
||||
elif val_method == 'FIFO':
|
||||
val_rate = self.get_fifo_inventory_values(in_rate, actual_qty = s['actual_qty'])
|
||||
return val_rate, stock_val
|
||||
|
||||
|
||||
# ----------------
|
||||
# get stock value
|
||||
# ----------------
|
||||
def get_stock_value(self, val_method, cqty, stock_val, serial_nos):
|
||||
if serial_nos:
|
||||
stock_val = flt(stock_val) * flt(cqty)
|
||||
elif val_method == 'Moving Average':
|
||||
stock_val = flt(cqty) > 0 and flt(stock_val) * flt(cqty) or 0
|
||||
elif val_method == 'FIFO':
|
||||
stock_val = sum([flt(d[0])*flt(d[1]) for d in self.fcfs_bal])
|
||||
return stock_val
|
||||
|
||||
def update_entries_after(self, posting_date, posting_time):
|
||||
"""
|
||||
update valution rate and qty after transaction
|
||||
from the current time-bucket onwards
|
||||
"""
|
||||
|
||||
# Get prev sle
|
||||
prev_sle = self.get_sle_prev_timebucket(posting_date, posting_time)
|
||||
|
||||
# if no prev sle, start from the first one (for repost)
|
||||
if not prev_sle:
|
||||
cqty, cval, val_rate, stock_val, self.fcfs_bal = 0, 0, 0, 0, []
|
||||
|
||||
# normal
|
||||
else:
|
||||
cqty = flt(prev_sle.get('bin_aqat', 0))
|
||||
cval =flt(prev_sle.get('stock_value', 0))
|
||||
val_rate = flt(prev_sle.get('valuation_rate', 0))
|
||||
self.fcfs_bal = eval(prev_sle.get('fcfs_stack', '[]') or '[]')
|
||||
|
||||
# get valuation method
|
||||
val_method = get_obj('Valuation Control').get_valuation_method(self.doc.item_code)
|
||||
|
||||
# allow negative stock (only for moving average method)
|
||||
from webnotes.utils import get_defaults
|
||||
allow_negative_stock = get_defaults().get('allow_negative_stock', 0)
|
||||
|
||||
|
||||
# recalculate the balances for all stock ledger entries
|
||||
# after the prev sle
|
||||
sll = sql("""
|
||||
select *
|
||||
from `tabStock Ledger Entry`
|
||||
where item_code = %s
|
||||
and warehouse = %s
|
||||
and ifnull(is_cancelled, 'No') = 'No'
|
||||
and timestamp(posting_date, posting_time) > timestamp(%s, %s)
|
||||
order by timestamp(posting_date, posting_time) asc, name asc""", \
|
||||
(self.doc.item_code, self.doc.warehouse, \
|
||||
prev_sle.get('posting_date','1900-01-01'), prev_sle.get('posting_time', '12:00')), as_dict = 1)
|
||||
for sle in sll:
|
||||
# block if stock level goes negative on any date
|
||||
if val_method != 'Moving Average' or flt(allow_negative_stock) == 0:
|
||||
self.validate_negative_stock(cqty, sle)
|
||||
|
||||
stock_val, in_rate = 0, sle['incoming_rate'] # IN
|
||||
serial_nos = sle["serial_no"] and ("'"+"', '".join(cstr(sle["serial_no"]).split('\n')) \
|
||||
+ "'") or ''
|
||||
|
||||
# Get valuation rate
|
||||
val_rate, stock_val = self.get_valuation_rate(val_method, serial_nos, \
|
||||
val_rate, in_rate, stock_val, cqty, sle)
|
||||
|
||||
# Qty upto the sle
|
||||
cqty += sle['actual_qty']
|
||||
|
||||
# Stock Value upto the sle
|
||||
stock_val = self.get_stock_value(val_method, cqty, stock_val, serial_nos)
|
||||
|
||||
# update current sle --> will it be good to update incoming rate in sle
|
||||
# for outgoing stock entry?????
|
||||
sql("""update `tabStock Ledger Entry`
|
||||
set bin_aqat=%s, valuation_rate=%s, fcfs_stack=%s, stock_value=%s
|
||||
where name=%s""", (cqty, flt(val_rate), cstr(self.fcfs_bal), stock_val, sle['name']))
|
||||
|
||||
# update the bin
|
||||
if sll or not prev_sle:
|
||||
sql("update `tabBin` set valuation_rate=%s, actual_qty=%s, stock_value = %s, projected_qty = (actual_qty + indented_qty + ordered_qty + planned_qty - reserved_qty) where name=%s", \
|
||||
(flt(val_rate), cqty, flt(stock_val), self.doc.name))
|
||||
|
||||
|
||||
|
||||
def reorder_item(self,doc_type,doc_name):
|
||||
""" Reorder item if stock reaches reorder level"""
|
||||
|
||||
if get_value('Global Defaults', None, 'auto_indent'):
|
||||
#check if re-order is required
|
||||
ret = sql("select re_order_level, item_name, description, brand, item_group, lead_time_days, min_order_qty, email_notify, re_order_qty from tabItem where name = %s", (self.doc.item_code), as_dict=1)
|
||||
|
||||
current_qty = sql("""
|
||||
select sum(t1.actual_qty) + sum(t1.indented_qty) + sum(t1.ordered_qty) -sum(t1.reserved_qty)
|
||||
from tabBin t1, tabWarehouse t2
|
||||
where t1.item_code = %s
|
||||
and t1.warehouse = t2.name
|
||||
and t2.warehouse_type in ('Stores', 'Reserved', 'Default Warehouse Type')
|
||||
and t1.docstatus != 2
|
||||
""", self.doc.item_code)
|
||||
|
||||
if ret[0]["re_order_level"] and current_qty and \
|
||||
(flt(ret[0]['re_order_level']) > flt(current_qty[0][0])):
|
||||
self.create_auto_indent(ret[0], doc_type, doc_name, current_qty[0][0])
|
||||
|
||||
|
||||
|
||||
def create_auto_indent(self, i , doc_type, doc_name, cur_qty):
|
||||
""" Create indent on reaching reorder level """
|
||||
|
||||
indent = Document('Purchase Request')
|
||||
indent.transaction_date = nowdate()
|
||||
indent.naming_series = 'IDT'
|
||||
indent.company = get_defaults()['company']
|
||||
indent.fiscal_year = get_defaults()['fiscal_year']
|
||||
indent.remark = "This is an auto generated Purchase Request. It was raised because the (actual + ordered + indented - reserved) quantity reaches re-order level when %s %s was created"%(doc_type,doc_name)
|
||||
indent.save(1)
|
||||
indent_obj = get_obj('Purchase Request',indent.name,with_children=1)
|
||||
indent_details_child = addchild(indent_obj.doc,'indent_details','Purchase Request Item',0)
|
||||
indent_details_child.item_code = self.doc.item_code
|
||||
indent_details_child.uom = self.doc.stock_uom
|
||||
indent_details_child.warehouse = self.doc.warehouse
|
||||
indent_details_child.schedule_date= add_days(nowdate(),cint(i['lead_time_days']))
|
||||
indent_details_child.item_name = i['item_name']
|
||||
indent_details_child.description = i['description']
|
||||
indent_details_child.item_group = i['item_group']
|
||||
indent_details_child.qty = i['re_order_qty'] or (flt(i['re_order_level']) - flt(cur_qty))
|
||||
indent_details_child.brand = i['brand']
|
||||
indent_details_child.save()
|
||||
indent_obj = get_obj('Purchase Request',indent.name,with_children=1)
|
||||
indent_obj.validate()
|
||||
set(indent_obj.doc,'docstatus',1)
|
||||
indent_obj.on_submit()
|
||||
msgprint("Item: " + self.doc.item_code + " is to be re-ordered. Purchase Request %s raised. It was generated from %s %s"%(indent.name,doc_type, doc_name ))
|
||||
if(i['email_notify']):
|
||||
self.send_email_notification(doc_type,doc_name)
|
||||
|
||||
|
||||
|
||||
def send_email_notification(self,doc_type,doc_name):
|
||||
""" Notify user about auto creation of indent"""
|
||||
|
||||
from webnotes.utils.email_lib import sendmail
|
||||
email_list=[d[0] for d in sql("select parent from tabUserRole where role in ('Purchase Manager','Material Manager') and parent not in ('Administrator', 'All', 'Guest')")]
|
||||
msg='A Purchase Request has been raised for item %s: %s on %s '%(doc_type, doc_name, nowdate())
|
||||
sendmail(email_list, subject='Auto Purchase Request Generation Notification', msg = msg)
|
||||
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.validate_mandatory()
|
||||
|
||||
|
||||
# set defaults in bin
|
||||
def validate_mandatory(self):
|
||||
qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty']
|
||||
for f in qf:
|
||||
if (not self.doc.fields.has_key(f)) or (not self.doc.fields[f]):
|
||||
self.doc.fields[f] = 0.0
|
||||
275
stock/doctype/bin/bin.txt
Normal file
275
stock/doctype/bin/bin.txt
Normal file
@@ -0,0 +1,275 @@
|
||||
# DocType, Bin
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-15 12:15:04',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-31 17:23:42',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1322549701',
|
||||
'autoname': u'BIN/.#######',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'hide_toolbar': 1,
|
||||
'in_create': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'read_only': 0,
|
||||
'search_fields': u'item_code,warehouse',
|
||||
'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'Bin',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Bin',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Bin
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Bin'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Purchase Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Purchase User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Material Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Warehouse',
|
||||
'oldfieldname': u'warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse_type',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Warehouse Type',
|
||||
'oldfieldname': u'warehouse_type',
|
||||
'oldfieldtype': u'Data'
|
||||
},
|
||||
|
||||
# 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',
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'reserved_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Reserved Quantity',
|
||||
'oldfieldname': u'reserved_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'actual_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 1,
|
||||
'label': u'Actual Quantity',
|
||||
'oldfieldname': u'actual_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ordered_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Ordered Quantity',
|
||||
'oldfieldname': u'ordered_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'indented_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Quantity Requested for Purchase',
|
||||
'oldfieldname': u'indented_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'planned_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Planned Qty',
|
||||
'oldfieldname': u'planned_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'projected_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Projected Qty',
|
||||
'oldfieldname': u'projected_qty',
|
||||
'oldfieldtype': u'Currency'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ma_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Moving Average Rate',
|
||||
'oldfieldname': u'ma_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fcfs_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'FCFS Rate',
|
||||
'oldfieldname': u'fcfs_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'valuation_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Valuation Rate',
|
||||
'oldfieldname': u'valuation_rate',
|
||||
'oldfieldtype': u'Currency'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_value',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Stock Value',
|
||||
'oldfieldname': u'stock_value',
|
||||
'oldfieldtype': u'Currency'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/delivery_note/__init__.py
Normal file
1
stock/doctype/delivery_note/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
332
stock/doctype/delivery_note/delivery_note.js
Normal file
332
stock/doctype/delivery_note/delivery_note.js
Normal file
@@ -0,0 +1,332 @@
|
||||
// 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 Material Management
|
||||
cur_frm.cscript.tname = "Delivery Note Item";
|
||||
cur_frm.cscript.fname = "delivery_note_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, dt, dn) {
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
||||
if(!doc.transaction_date) set_multiple(dt,dn,{transaction_date:get_today()});
|
||||
if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()});
|
||||
if(doc.__islocal && doc.customer) cur_frm.cscript.customer(doc,dt,dn,onload=true);
|
||||
if(!doc.price_list_currency) {
|
||||
set_multiple(dt, dn, {price_list_currency: doc.currency, plc_conversion_rate:1});
|
||||
}
|
||||
if(!doc.posting_time) doc.posting_time = wn.datetime.get_cur_time()
|
||||
|
||||
if(doc.__islocal){
|
||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
|
||||
// defined in sales_common.js
|
||||
var callback = function(doc, dt, dn) {
|
||||
if(doc.__islocal) cur_frm.cscript.update_item_details(doc, dt, dn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_price_list_currency(doc, dt, dn, callback);
|
||||
}
|
||||
|
||||
// REFRESH
|
||||
// ================================================================================================
|
||||
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.per_billed < 100 && doc.docstatus==1) cur_frm.add_custom_button('Make Invoice', cur_frm.cscript['Make Sales Invoice']);
|
||||
|
||||
if(doc.per_installed < 100 && doc.docstatus==1) cur_frm.add_custom_button('Make Installation Note', cur_frm.cscript['Make Installation Note']);
|
||||
|
||||
if (doc.docstatus==1) cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
|
||||
if(doc.docstatus==0 && !doc.__islocal) {
|
||||
cur_frm.add_custom_button('Make Packing Slip', cur_frm.cscript['Make Packing Slip']);
|
||||
}
|
||||
|
||||
if(doc.customer) $(cur_frm.fields_dict.contact_info.row.wrapper).toggle(true);
|
||||
else $(cur_frm.fields_dict.contact_info.row.wrapper).toggle(false);
|
||||
|
||||
set_print_hide(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn,onload) {
|
||||
var pl = doc.price_list_name;
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
if(doc.customer) unhide_field(['customer_address','contact_person','territory','customer_group']);
|
||||
cur_frm.refresh();
|
||||
if(!onload && (pl != doc.price_list_name)) cur_frm.cscript.price_list_name(doc, dt, dn);
|
||||
}
|
||||
var args = onload ? 'onload':''
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_shipping_address', args, 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.get_items = function(doc,dt,dn) {
|
||||
var callback = function(r,rt){
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
if(r.message){
|
||||
doc.sales_order_no = r.message;
|
||||
if(doc.sales_order_no) {
|
||||
unhide_field(['customer_address','contact_person','territory','customer_group']);
|
||||
}
|
||||
refresh_many(['delivery_note_details','customer','customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
}
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_sales_order_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);
|
||||
}
|
||||
|
||||
//========================= Overloaded query for link batch_no =============================================================
|
||||
cur_frm.fields_dict['delivery_note_details'].grid.get_field('batch_no').get_query= function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.item_code){
|
||||
return "SELECT tabBatch.name, tabBatch.description FROM tabBatch WHERE tabBatch.docstatus != 2 AND tabBatch.item = '"+ d.item_code +"' AND `tabBatch`.`name` like '%s' ORDER BY `tabBatch`.`name` DESC LIMIT 50"
|
||||
}
|
||||
else{
|
||||
alert("Please enter Item Code.");
|
||||
}
|
||||
}
|
||||
|
||||
// ***************** 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});
|
||||
}
|
||||
|
||||
|
||||
// *************** Customized link query for SALES ORDER based on customer and currency*****************************
|
||||
cur_frm.fields_dict['sales_order_no'].get_query = function(doc) {
|
||||
doc = locals[this.doctype][this.docname];
|
||||
var cond = '';
|
||||
|
||||
if(doc.customer) {
|
||||
cond = '`tabSales Order`.customer = "'+doc.customer+'" and';
|
||||
}
|
||||
|
||||
if(doc.project_name){
|
||||
cond += '`tabSales Order`.project_name ="'+doc.project_name+'"';
|
||||
}
|
||||
return repl('SELECT DISTINCT `tabSales Order`.`name` FROM `tabSales Order` WHERE `tabSales Order`.company = "%(company)s" and `tabSales Order`.`docstatus` = 1 and `tabSales Order`.`status` != "Stopped" and ifnull(`tabSales Order`.per_delivered,0) < 100 and %(cond)s `tabSales Order`.%(key)s LIKE "%s" ORDER BY `tabSales Order`.`name` DESC LIMIT 50', {company:doc.company,cond:cond})
|
||||
}
|
||||
|
||||
|
||||
// ****************************** DELIVERY TYPE ************************************
|
||||
cur_frm.cscript.delivery_type = function(doc, cdt, cdn) {
|
||||
if (doc.delivery_type = 'Sample') cfn_set_fields(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.serial_no = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.serial_no) {
|
||||
get_server_fields('get_serial_details',d.serial_no,'delivery_note_details',doc,cdt,cdn,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.warehouse = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (! d.item_code) {alert("please enter item code first"); return};
|
||||
if (d.warehouse) {
|
||||
arg = "{'item_code':'" + d.item_code + "','warehouse':'" + d.warehouse +"'}";
|
||||
get_server_fields('get_actual_qty',arg,'delivery_note_details',doc,cdt,cdn,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['transporter_name'].get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabSupplier`.`name` FROM `tabSupplier` WHERE `tabSupplier`.supplier_type = "transporter" AND `tabSupplier`.docstatus != 2 AND `tabSupplier`.%(key)s LIKE "%s" ORDER BY `tabSupplier`.`name` LIMIT 50';
|
||||
}
|
||||
|
||||
//-----------------------------------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':"[['Delivery Note','Sales Invoice'],['Delivery Note Item','Sales Invoice Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc('Sales Invoice', n);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//-----------------------------------Make Installation Note----------------------------------------------
|
||||
cur_frm.cscript['Make Installation Note'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
if(doc.per_installed < 100){
|
||||
n = createLocal('Installation Note');
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals['Installation Note'][n]]),
|
||||
'from_doctype':doc.doctype,
|
||||
'to_doctype':'Installation Note',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Delivery Note','Installation Note'],['Delivery Note Item','Installation Note Item']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc('Installation Note', n);
|
||||
}
|
||||
);
|
||||
}
|
||||
else if(doc.per_installed >= 100)
|
||||
msgprint("Item installation is already completed")
|
||||
}
|
||||
|
||||
//-----------------------------------Make Sales Invoice----------------------------------------------
|
||||
cur_frm.cscript['Make Packing Slip'] = function() {
|
||||
var doc = cur_frm.doc
|
||||
n = createLocal('Packing Slip');
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals['Packing Slip'][n]]),
|
||||
'from_doctype':doc.doctype,
|
||||
'to_doctype':'Packing Slip',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Delivery Note','Packing Slip'],['Delivery Note Item','Packing Slip Item']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc('Packing Slip', 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';
|
||||
}
|
||||
|
||||
//------------------------for printing without amount----------
|
||||
|
||||
var set_print_hide= function(doc, cdt, cdn){
|
||||
var dn_fields = wn.meta.docfield_map['Delivery Note'];
|
||||
var dn_item_fields = wn.meta.docfield_map['Delivery Note Item'];
|
||||
|
||||
if (doc.print_without_amount) {
|
||||
dn_fields['currency'].print_hide = 1;
|
||||
dn_item_fields['export_rate'].print_hide = 1;
|
||||
dn_item_fields['adj_rate'].print_hide = 1;
|
||||
dn_item_fields['ref_rate'].print_hide = 1;
|
||||
dn_item_fields['export_amount'].print_hide = 1;
|
||||
} else {
|
||||
dn_fields['currency'].print_hide = 0;
|
||||
dn_item_fields['export_rate'].print_hide = 0;
|
||||
dn_item_fields['adj_rate'].print_hide = 0;
|
||||
dn_item_fields['ref_rate'].print_hide = 0;
|
||||
dn_item_fields['export_amount'].print_hide = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.print_without_amount = function(doc, cdt, cdn) {
|
||||
set_print_hide(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
//****************** For print sales order no and date*************************
|
||||
cur_frm.pformat.sales_order_no= function(doc, cdt, cdn){
|
||||
//function to make row of table
|
||||
|
||||
var make_row = function(title,val1, val2, bold){
|
||||
var bstart = '<b>'; var bend = '</b>';
|
||||
|
||||
return '<tr><td style="width:39%;">'+(bold?bstart:'')+title+(bold?bend:'')+'</td>'
|
||||
+'<td style="width:61%;text-align:left;">'+val1+(val2?' ('+dateutil.str_to_user(val2)+')':'')+'</td>'
|
||||
+'</tr>'
|
||||
}
|
||||
|
||||
out ='';
|
||||
|
||||
var cl = getchildren('Delivery Note Item',doc.name,'delivery_note_details');
|
||||
|
||||
// outer table
|
||||
var out='<div><table class="noborder" style="width:100%"><tr><td style="width: 50%"></td><td>';
|
||||
|
||||
// main table
|
||||
out +='<table class="noborder" style="width:100%">';
|
||||
|
||||
// add rows
|
||||
if(cl.length){
|
||||
prevdoc_list = new Array();
|
||||
for(var i=0;i<cl.length;i++){
|
||||
if(cl[i].prevdoc_doctype == 'Sales Order' && cl[i].prevdoc_docname && prevdoc_list.indexOf(cl[i].prevdoc_docname) == -1) {
|
||||
prevdoc_list.push(cl[i].prevdoc_docname);
|
||||
if(prevdoc_list.length ==1)
|
||||
out += make_row(cl[i].prevdoc_doctype, cl[i].prevdoc_docname, cl[i].prevdoc_date,0);
|
||||
else
|
||||
out += make_row('', cl[i].prevdoc_docname, cl[i].prevdoc_date,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out +='</table></td></tr></table></div>';
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
||||
var args = {
|
||||
type: 'Delivery Note',
|
||||
doctype: 'Delivery Note'
|
||||
}
|
||||
cur_frm.cscript.notify(doc, args);
|
||||
}
|
||||
411
stock/doctype/delivery_note/delivery_note.py
Normal file
411
stock/doctype/delivery_note/delivery_note.py
Normal file
@@ -0,0 +1,411 @@
|
||||
# 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 = 'Delivery Note Item'
|
||||
self.fname = 'delivery_note_details'
|
||||
|
||||
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
def validate_fiscal_year(self):
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
|
||||
|
||||
|
||||
def get_contact_details(self):
|
||||
return get_obj('Sales Common').get_contact_details(self,0)
|
||||
|
||||
|
||||
def get_comm_rate(self, sales_partner):
|
||||
"""Get Commission rate of Sales Partner"""
|
||||
return get_obj('Sales Common').get_comm_rate(sales_partner, self)
|
||||
|
||||
|
||||
def pull_sales_order_details(self):
|
||||
self.validate_prev_docname()
|
||||
self.doclist = self.doc.clear_table(self.doclist,'other_charges')
|
||||
|
||||
if self.doc.sales_order_no:
|
||||
get_obj('DocType Mapper', 'Sales Order-Delivery Note').dt_map('Sales Order', 'Delivery Note', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Delivery Note'],['Sales Order Item', 'Delivery Note Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]")
|
||||
else:
|
||||
msgprint("Please select Sales Order No. whose details need to be pulled")
|
||||
|
||||
return cstr(self.doc.sales_order_no)
|
||||
|
||||
|
||||
def validate_prev_docname(self):
|
||||
"""Validates that Sales Order is not pulled twice"""
|
||||
for d in getlist(self.doclist, 'delivery_note_details'):
|
||||
if self.doc.sales_order_no == d.prevdoc_docname:
|
||||
msgprint(cstr(self.doc.sales_order_no) + " sales order details have already been pulled. ")
|
||||
raise Exception, "Validation Error. "
|
||||
|
||||
|
||||
def set_actual_qty(self):
|
||||
for d in getlist(self.doclist, 'delivery_note_details'):
|
||||
if d.item_code and d.warehouse:
|
||||
actual_qty = sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code, d.warehouse))
|
||||
d.actual_qty = actual_qty and flt(actual_qty[0][0]) or 0
|
||||
|
||||
|
||||
def get_tc_details(self):
|
||||
return get_obj('Sales Common').get_tc_details(self)
|
||||
|
||||
|
||||
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-Delivery Note').dt_map('Project', 'Delivery Note', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Delivery Note']]")
|
||||
|
||||
|
||||
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]
|
||||
|
||||
def get_barcode_details(self, barcode):
|
||||
return get_obj('Sales Common').get_barcode_details(barcode)
|
||||
|
||||
|
||||
def get_adj_percent(self, arg=''):
|
||||
"""Re-calculates Basic Rate & amount based on Price List Selected"""
|
||||
get_obj('Sales Common').get_adj_percent(self)
|
||||
|
||||
|
||||
def get_actual_qty(self,args):
|
||||
"""Get Actual Qty of item in warehouse selected"""
|
||||
return get_obj('Sales Common').get_available_qty(eval(args))
|
||||
|
||||
|
||||
def get_rate(self,arg):
|
||||
return get_obj('Sales Common').get_rate(arg)
|
||||
|
||||
|
||||
def load_default_taxes(self):
|
||||
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
||||
|
||||
|
||||
def get_other_charges(self):
|
||||
"""Pull details from Sales Taxes and Charges Master"""
|
||||
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
||||
|
||||
|
||||
def so_required(self):
|
||||
"""check in manage account if sales order required or not"""
|
||||
if webnotes.conn.get_value('Global Defaults', 'Global Defaults', 'so_required') == 'Yes':
|
||||
for d in getlist(self.doclist,'delivery_note_details'):
|
||||
if not d.prevdoc_docname:
|
||||
msgprint("Sales Order No. required against item %s"%d.item_code)
|
||||
raise Exception
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.so_required()
|
||||
self.validate_fiscal_year()
|
||||
self.validate_proj_cust()
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.check_stop_sales_order(self)
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.get_prevdoc_date(self)
|
||||
self.validate_mandatory()
|
||||
self.validate_reference_value()
|
||||
self.validate_for_items()
|
||||
sales_com_obj.validate_max_discount(self, 'delivery_note_details') #verify whether rate is not greater than max discount
|
||||
sales_com_obj.get_allocated_sum(self) # this is to verify that the allocated % of sales persons is 100%
|
||||
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)
|
||||
|
||||
# Set actual qty for each item in selected warehouse
|
||||
self.update_current_stock()
|
||||
|
||||
self.doc.status = 'Draft'
|
||||
if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
|
||||
if not self.doc.installation_status: self.doc.installation_status = 'Not Installed'
|
||||
|
||||
|
||||
def validate_mandatory(self):
|
||||
if self.doc.amended_from and not self.doc.amendment_date:
|
||||
msgprint("Please Enter Amendment Date")
|
||||
raise Exception, "Validation Error. "
|
||||
|
||||
|
||||
def validate_proj_cust(self):
|
||||
"""check for does customer belong to same project as entered.."""
|
||||
if self.doc.project_name and self.doc.customer:
|
||||
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
|
||||
|
||||
|
||||
def validate_reference_value(self):
|
||||
"""Validate values with reference document with previous document"""
|
||||
get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||
|
||||
|
||||
def validate_for_items(self):
|
||||
check_list, chk_dupl_itm = [], []
|
||||
for d in getlist(self.doclist,'delivery_note_details'):
|
||||
ch = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
|
||||
if d.prevdoc_doctype and d.prevdoc_detail_docname and ch and ch[0][0]=='Yes':
|
||||
self.validate_items_with_prevdoc(d)
|
||||
|
||||
# validates whether item is not entered twice
|
||||
e = [d.item_code, d.description, d.warehouse, d.prevdoc_docname or '', d.batch_no or '']
|
||||
f = [d.item_code, d.description, d.prevdoc_docname or '']
|
||||
|
||||
if ch and ch[0][0] == 'Yes':
|
||||
if e in check_list:
|
||||
msgprint("Please check whether item %s has been entered twice wrongly." % d.item_code)
|
||||
else:
|
||||
check_list.append(e)
|
||||
elif ch and ch[0][0] == 'No':
|
||||
if f in chk_dupl_itm:
|
||||
msgprint("Please check whether item %s has been entered twice wrongly." % d.item_code)
|
||||
else:
|
||||
chk_dupl_itm.append(f)
|
||||
|
||||
|
||||
def validate_items_with_prevdoc(self, d):
|
||||
"""check if same item, warehouse present in prevdoc"""
|
||||
prev_item_dt = (d.prevdoc_doctype == 'Sales Order') and 'Sales Order Item' or 'Purchase Receipt Item'
|
||||
data = sql("select item_code from `tab%s` where parent = '%s' and name = '%s'"\
|
||||
% (prev_item_dt, d.prevdoc_docname, d.prevdoc_detail_docname))
|
||||
if not data or data[0][0] != d.item_code:
|
||||
msgprint("Item: %s is not matching with Sales Order: %s. Sales Order might be modified after \
|
||||
fetching data from it. Please delete items and fetch again." \
|
||||
% (d.item_code, d.prevdoc_docname), raise_exception=1)
|
||||
|
||||
|
||||
def update_current_stock(self):
|
||||
for d in getlist(self.doclist, 'delivery_note_details'):
|
||||
bin = sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
|
||||
d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
|
||||
|
||||
for d in getlist(self.doclist, 'packing_details'):
|
||||
bin = sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
|
||||
d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
|
||||
d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
|
||||
|
||||
|
||||
def on_submit(self):
|
||||
self.validate_packed_qty()
|
||||
set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_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)
|
||||
|
||||
# validate serial no for item table (non-sales-bom item) and packing list (sales-bom item)
|
||||
sl_obj = get_obj("Stock Ledger")
|
||||
sl_obj.validate_serial_no(self, 'delivery_note_details')
|
||||
sl_obj.validate_serial_no_warehouse(self, 'delivery_note_details')
|
||||
sl_obj.validate_serial_no(self, 'packing_details')
|
||||
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
|
||||
|
||||
# update delivery details in serial no
|
||||
sl_obj.update_serial_record(self, 'delivery_note_details', is_submit = 1, is_incoming = 0)
|
||||
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
|
||||
|
||||
# update delivered qty in sales order
|
||||
get_obj("Sales Common").update_prevdoc_detail(1,self)
|
||||
|
||||
# create stock ledger entry
|
||||
self.update_stock_ledger(update_stock = 1)
|
||||
|
||||
self.credit_limit()
|
||||
|
||||
# set DN status
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
|
||||
def validate_packed_qty(self):
|
||||
"""
|
||||
Validate that if packed qty exists, it should be equal to qty
|
||||
"""
|
||||
if not any([flt(d.fields.get('packed_qty')) for d in self.doclist if
|
||||
d.doctype=='Delivery Note Item']):
|
||||
return
|
||||
packing_error_list = []
|
||||
for d in self.doclist:
|
||||
if d.doctype != 'Delivery Note Item': continue
|
||||
if flt(d.fields.get('qty')) != flt(d.fields.get('packed_qty')):
|
||||
packing_error_list.append([
|
||||
d.fields.get('item_code', ''),
|
||||
d.fields.get('qty', 0),
|
||||
d.fields.get('packed_qty', 0)
|
||||
])
|
||||
if packing_error_list:
|
||||
from webnotes.utils import cstr
|
||||
err_msg = "\n".join([("Item: " + d[0] + ", Qty: " + cstr(d[1]) \
|
||||
+ ", Packed: " + cstr(d[2])) for d in packing_error_list])
|
||||
webnotes.msgprint("Packing Error:\n" + err_msg, raise_exception=1)
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.check_stop_sales_order(self)
|
||||
self.check_next_docstatus()
|
||||
|
||||
# remove delivery details from serial no
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.update_serial_record(self, 'delivery_note_details', is_submit = 0, is_incoming = 0)
|
||||
sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
|
||||
|
||||
sales_com_obj.update_prevdoc_detail(0,self)
|
||||
self.update_stock_ledger(update_stock = -1)
|
||||
set(self.doc, 'status', 'Cancelled')
|
||||
self.cancel_packing_slips()
|
||||
|
||||
|
||||
def check_next_docstatus(self):
|
||||
submit_rv = sql("select t1.name from `tabSales Invoice` t1,`tabSales Invoice Item` t2 where t1.name = t2.parent and t2.delivery_note = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||
if submit_rv:
|
||||
msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted !")
|
||||
raise Exception , "Validation Error."
|
||||
|
||||
submit_in = sql("select t1.name from `tabInstallation Note` t1, `tabInstallation Note Item` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||
if submit_in:
|
||||
msgprint("Installation Note : "+cstr(submit_in[0][0]) +" has already been submitted !")
|
||||
raise Exception , "Validation Error."
|
||||
|
||||
|
||||
def cancel_packing_slips(self):
|
||||
"""
|
||||
Cancel submitted packing slips related to this delivery note
|
||||
"""
|
||||
res = webnotes.conn.sql("""\
|
||||
SELECT name, count(*) FROM `tabPacking Slip`
|
||||
WHERE delivery_note = %s AND docstatus = 1
|
||||
""", self.doc.name)
|
||||
|
||||
if res and res[0][1]>0:
|
||||
from webnotes.model.doclist import DocList
|
||||
for r in res:
|
||||
ps = DocList(dt='Packing Slip', dn=r[0])
|
||||
ps.cancel()
|
||||
webnotes.msgprint("%s Packing Slip(s) Cancelled" % res[0][1])
|
||||
|
||||
|
||||
def update_stock_ledger(self, update_stock, is_stopped = 0):
|
||||
self.values = []
|
||||
for d in self.get_item_list(is_stopped):
|
||||
stock_item = sql("SELECT is_stock_item, is_sample_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[0]['is_stock_item'] == "Yes":
|
||||
if not d['warehouse']:
|
||||
msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d['item_code'])
|
||||
raise Exception
|
||||
if d['reserved_qty'] < 0 :
|
||||
# Reduce reserved qty from reserved warehouse mentioned in so
|
||||
bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin(0, flt(update_stock) * flt(d['reserved_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'))
|
||||
|
||||
# Reduce actual qty from warehouse
|
||||
self.make_sl_entry(d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
|
||||
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
|
||||
|
||||
|
||||
def get_item_list(self, is_stopped):
|
||||
return get_obj('Sales Common').get_item_list(self, is_stopped)
|
||||
|
||||
|
||||
def make_sl_entry(self, d, wh, qty, in_value, update_stock):
|
||||
self.values.append({
|
||||
'item_code' : d['item_code'],
|
||||
'warehouse' : wh,
|
||||
'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'),
|
||||
'posting_date' : self.doc.posting_date,
|
||||
'posting_time' : self.doc.posting_time,
|
||||
'voucher_type' : 'Delivery Note',
|
||||
'voucher_no' : self.doc.name,
|
||||
'voucher_detail_no' : d['name'],
|
||||
'actual_qty' : qty,
|
||||
'stock_uom' : d['uom'],
|
||||
'incoming_rate' : in_value,
|
||||
'company' : self.doc.company,
|
||||
'fiscal_year' : self.doc.fiscal_year,
|
||||
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
|
||||
'batch_no' : d['batch_no'],
|
||||
'serial_no' : d['serial_no']
|
||||
})
|
||||
|
||||
|
||||
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))
|
||||
|
||||
|
||||
def credit_limit(self):
|
||||
"""check credit limit of items in DN Detail which are not fetched from sales order"""
|
||||
amount, total = 0, 0
|
||||
for d in getlist(self.doclist, 'delivery_note_details'):
|
||||
if not d.prevdoc_docname:
|
||||
amount += d.amount
|
||||
if amount != 0:
|
||||
total = (amount/self.doc.net_total)*self.doc.grand_total
|
||||
get_obj('Sales Common').check_credit(self, total)
|
||||
|
||||
|
||||
def on_update(self):
|
||||
self.doclist = get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.scrub_serial_nos(self)
|
||||
sl.scrub_serial_nos(self, 'packing_details')
|
||||
|
||||
1471
stock/doctype/delivery_note/delivery_note.txt
Normal file
1471
stock/doctype/delivery_note/delivery_note.txt
Normal file
File diff suppressed because it is too large
Load Diff
22
stock/doctype/delivery_note/delivery_note_list.js
Normal file
22
stock/doctype/delivery_note/delivery_note_list.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// render
|
||||
wn.doclistviews['Delivery Note'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d);
|
||||
this.fields = this.fields.concat([
|
||||
"`tabDelivery Note`.customer_name",
|
||||
"`tabDelivery Note`.sales_order_no",
|
||||
"`tabDelivery Note`.posting_date",
|
||||
]);
|
||||
},
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '3%', content:'docstatus'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '47%', content:'customer_name+tags', css: {color:'#222'}},
|
||||
{width: '15%', content:'sales_order_no', type:'link', doctype:'Sales Order'},
|
||||
{width: '12%', content:'posting_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Delivery Note Date", type: "date"}
|
||||
]
|
||||
});
|
||||
1
stock/doctype/delivery_note_item/__init__.py
Normal file
1
stock/doctype/delivery_note_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
458
stock/doctype/delivery_note_item/delivery_note_item.txt
Normal file
458
stock/doctype/delivery_note_item/delivery_note_item.txt
Normal file
@@ -0,0 +1,458 @@
|
||||
# DocType, Delivery Note Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-06-08 16:08:01',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-09 11:06:26',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1311621379',
|
||||
'autoname': u'DND/.#######',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'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'Delivery Note Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Delivery Note Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Delivery Note Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'barcode',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Barcode',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# 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
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'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'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'reqd': 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',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate',
|
||||
'no_copy': 0,
|
||||
'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
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'export_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount',
|
||||
'oldfieldname': u'export_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'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'Rate*',
|
||||
'oldfieldname': u'basic_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount*',
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Warehouse',
|
||||
'oldfieldname': u'warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Text',
|
||||
'in_filter': 1,
|
||||
'label': u'Serial No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'serial_no',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'batch_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Batch No',
|
||||
'oldfieldname': u'batch_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Batch',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# 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',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Brand Name',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'actual_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Available Qty at Warehouse',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'actual_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'billed_amt',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Billed Amt',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'installed_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Installed Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'installed_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 1,
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'packed_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Packed Quantity',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_doctype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Document Type',
|
||||
'oldfieldname': u'prevdoc_doctype',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'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_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Against Document Date',
|
||||
'oldfieldname': u'prevdoc_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_detail_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Against Document Detail No',
|
||||
'oldfieldname': u'prevdoc_detail_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 0,
|
||||
'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
|
||||
},
|
||||
|
||||
# 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
|
||||
}
|
||||
]
|
||||
1
stock/doctype/delivery_note_packing_item/__init__.py
Normal file
1
stock/doctype/delivery_note_packing_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,208 @@
|
||||
# DocType, Delivery Note Packing Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-06-11 12:10:10',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-10 12:05:31',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'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'Delivery Note Packing Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Delivery Note Packing Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Delivery Note Packing Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'parent_item',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Parent Item',
|
||||
'oldfieldname': u'parent_item',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'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': 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': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'parent_detail_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Parent Detail docname',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'parent_detail_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Warehouse',
|
||||
'oldfieldname': u'warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'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'actual_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Actual Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'actual_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'projected_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Projected Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'projected_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# 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
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_doctype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Prevdoc DocType',
|
||||
'oldfieldname': u'prevdoc_doctype',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 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': 1
|
||||
}
|
||||
]
|
||||
1
stock/doctype/item/__init__.py
Normal file
1
stock/doctype/item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
144
stock/doctype/item/item.js
Normal file
144
stock/doctype/item/item.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/>.
|
||||
|
||||
cur_frm.cscript.refresh = function(doc) {
|
||||
// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
|
||||
// read only if any stock ledger entry exists
|
||||
|
||||
if (!doc.__islocal) {
|
||||
set_field_permlevel("item_code", 1);
|
||||
}
|
||||
|
||||
if ((!doc.__islocal) && (doc.is_stock_item == 'Yes')) {
|
||||
var callback = function(r, rt) {
|
||||
if (r.message == 'exists') permlevel = 1;
|
||||
else permlevel = 0;
|
||||
|
||||
set_field_permlevel('has_serial_no', permlevel);
|
||||
set_field_permlevel('is_stock_item', permlevel);
|
||||
set_field_permlevel('valuation_method', permlevel);
|
||||
}
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'check_if_sle_exists','',callback);
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_website_fields(doc);
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_website_fields = function(doc) {
|
||||
var website_fields_list = ['page_name', 'website_image', 'web_short_description',
|
||||
'web_long_description'];
|
||||
if (doc && cint(doc.show_in_website)) {
|
||||
unhide_field(website_fields_list);
|
||||
} else {
|
||||
hide_field(website_fields_list);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.show_in_website = function(doc, dt, dn) {
|
||||
cur_frm.cscript.hide_website_fields(doc);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['default_bom'].get_query = function(doc) {
|
||||
//var d = locals[this.doctype][this.docname];
|
||||
return 'SELECT DISTINCT `tabBOM`.`name` FROM `tabBOM` WHERE `tabBOM`.`item` = "' + doc.item_code + '" AND `tabBOM`.`is_active` = "No" and `tabBOM`.docstatus != 2 AND `tabBOM`.%(key)s LIKE "%s" ORDER BY `tabBOM`.`name` LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Expense Account
|
||||
// ---------------------------------
|
||||
cur_frm.fields_dict['purchase_account'].get_query = function(doc){
|
||||
return 'SELECT DISTINCT `tabAccount`.`name` FROM `tabAccount` WHERE `tabAccount`.`debit_or_credit`="Debit" AND `tabAccount`.`group_or_ledger`="Ledger" AND `tabAccount`.`docstatus`!=2 AND `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.`name` LIMIT 50'
|
||||
}
|
||||
|
||||
// Income Account
|
||||
// --------------------------------
|
||||
cur_frm.fields_dict['default_income_account'].get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabAccount`.`name` FROM `tabAccount` WHERE `tabAccount`.`debit_or_credit`="Credit" AND `tabAccount`.`group_or_ledger`="Ledger" AND `tabAccount`.`docstatus`!=2 AND `tabAccount`.`account_type` ="Income Account" AND `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.`name` LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Purchase Cost Center
|
||||
// -----------------------------
|
||||
cur_frm.fields_dict['cost_center'].get_query = function(doc) {
|
||||
return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Sales Cost Center
|
||||
// -----------------------------
|
||||
cur_frm.fields_dict['default_sales_cost_center'].get_query = function(doc) {
|
||||
return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['item_tax'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT `tabAccount`.`name` FROM `tabAccount` WHERE `tabAccount`.`account_type` in ("Tax", "Chargeable") and `tabAccount`.`docstatus` != 2 and `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.`name` DESC LIMIT 50'
|
||||
}
|
||||
|
||||
cur_frm.cscript.tax_type = function(doc, cdt, cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
get_server_fields('get_tax_rate',d.tax_type,'item_tax',doc, cdt, cdn, 1);
|
||||
}
|
||||
|
||||
|
||||
//get query select item group
|
||||
cur_frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabItem Group`.`name`,`tabItem Group`.`parent_item_group` FROM `tabItem Group` WHERE `tabItem Group`.`is_group` = "No" AND `tabItem Group`.`docstatus`!= 2 AND `tabItem Group`.%(key)s LIKE "%s" ORDER BY `tabItem Group`.`name` ASC LIMIT 50'
|
||||
}
|
||||
|
||||
// for description from attachment
|
||||
// takes the first attachment and creates
|
||||
// a table with both image and attachment in HTML
|
||||
// in the "alternate_description" field
|
||||
cur_frm.cscript.add_image = function(doc, dt, dn) {
|
||||
if(!doc.file_list) {
|
||||
msgprint('Please attach a file first!');
|
||||
}
|
||||
|
||||
var f = doc.file_list.split('\n')[0];
|
||||
var fname = f.split(',')[0];
|
||||
var fid = f.split(',')[1];
|
||||
if(!in_list(['jpg','jpeg','gif','png'], fname.split('.')[1].toLowerCase())) {
|
||||
msgprint('File must be of extension jpg, jpeg, gif or png'); return;
|
||||
}
|
||||
|
||||
doc.description_html = repl('<table style="width: 100%; table-layout: fixed;">'+
|
||||
'<tr><td style="width:110px"><img src="%(imgurl)s" width="100px"></td>'+
|
||||
'<td>%(desc)s</td></tr>'+
|
||||
'</table>', {imgurl: wn.urllib.get_file_url(fid), desc:doc.description});
|
||||
|
||||
refresh_field('description_html');
|
||||
}
|
||||
//===================== Quotation to validation - either customer or lead mandatory ====================
|
||||
cur_frm.cscript.weight_to_validate = function(doc,cdt,cdn){
|
||||
|
||||
if((doc.nett_weight || doc.gross_weight) && !doc.weight_uom)
|
||||
{
|
||||
alert('Weight is mentioned,\nPlease mention "Weight UOM" too');
|
||||
validated=0;
|
||||
}
|
||||
}
|
||||
//===================validation function =================================
|
||||
|
||||
cur_frm.cscript.validate = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.weight_to_validate(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
//===========Fill Default Currency in "Item Prices====================
|
||||
cur_frm.fields_dict['ref_rate_details'].grid.onrowadd = function(doc, cdt, cdn){
|
||||
locals[cdt][cdn].ref_currency = sys_defaults.currency;
|
||||
refresh_field('ref_currency',cdn,'ref_rate_details');
|
||||
}
|
||||
240
stock/doctype/item/item.py
Normal file
240
stock/doctype/item/item.py
Normal file
@@ -0,0 +1,240 @@
|
||||
# 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 get_tax_rate(self, tax_type):
|
||||
rate = sql("select tax_rate from tabAccount where name = %s", tax_type)
|
||||
ret = {
|
||||
'tax_rate' : rate and flt(rate[0][0]) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
def on_update(self):
|
||||
self.update_page_name()
|
||||
|
||||
bin = sql("select stock_uom from `tabBin` where item_code = '%s' " % self.doc.item_code)
|
||||
if bin and cstr(bin[0][0]) != cstr(self.doc.stock_uom):
|
||||
msgprint("Please Update Stock UOM with the help of Stock UOM Replace Utility.")
|
||||
raise Exception
|
||||
check_list = []
|
||||
for d in getlist(self.doclist,'uom_conversion_details'):
|
||||
if not self.doc.stock_uom:
|
||||
msgprint("Please enter Stock UOM first.")
|
||||
raise Exception
|
||||
|
||||
if cstr(d.uom) in check_list:
|
||||
msgprint("UOM %s has been entered more than once in Conversion Factor Details." % cstr(d.uom))
|
||||
raise Exception
|
||||
else:
|
||||
check_list.append(cstr(d.uom))
|
||||
|
||||
if cstr(d.uom) == cstr(self.doc.stock_uom):
|
||||
if flt(d.conversion_factor) != 1:
|
||||
msgprint("Conversion Factor of UOM : %s should be equal to 1. As UOM : %s is Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
# else set uom_exist as true
|
||||
uom_exist='true'
|
||||
elif cstr(d.uom) != cstr(self.doc.stock_uom) and flt(d.conversion_factor) == 1:
|
||||
msgprint("Conversion Factor of UOM : %s should not be equal to 1. As UOM : %s is not Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
|
||||
if not cstr(self.doc.stock_uom) in check_list :
|
||||
child = addchild( self.doc, 'uom_conversion_details', 'UOM Conversion Detail', 1, self.doclist)
|
||||
child.uom = self.doc.stock_uom
|
||||
child.conversion_factor = 1
|
||||
child.save()
|
||||
|
||||
self.clear_web_cache()
|
||||
|
||||
# On delete 1. Delete BIN (if none of the corrosponding transactions present, it gets deleted. if present, rolled back due to exception)
|
||||
def on_trash(self):
|
||||
sql("delete from tabBin where item_code='%s'"%(self.doc.item_code))
|
||||
|
||||
self.delete_web_cache(self.doc.page_name)
|
||||
|
||||
# Check whether Ref Rate is not entered twice for same Price List and Currency
|
||||
def check_ref_rate_detail(self):
|
||||
check_list=[]
|
||||
for d in getlist(self.doclist,'ref_rate_details'):
|
||||
if [cstr(d.price_list_name),cstr(d.ref_currency)] in check_list:
|
||||
msgprint("Ref Rate is entered twice for Price List : '%s' and Currency : '%s'." % (d.price_list_name,d.ref_currency))
|
||||
raise Exception
|
||||
else:
|
||||
check_list.append([cstr(d.price_list_name),cstr(d.ref_currency)])
|
||||
|
||||
# Append all the customer codes and insert into "customer_code" field of item table
|
||||
def fill_customer_code(self):
|
||||
cust_code=[]
|
||||
for d in getlist(self.doclist,'item_customer_details'):
|
||||
cust_code.append(d.ref_code)
|
||||
self.doc.customer_code=','.join(cust_code)
|
||||
|
||||
# Check whether Tax Rate is not entered twice for same Tax Type
|
||||
def check_item_tax(self):
|
||||
check_list=[]
|
||||
for d in getlist(self.doclist,'item_tax'):
|
||||
account_type = sql("select account_type from tabAccount where name = %s",d.tax_type)
|
||||
account_type = account_type and account_type[0][0] or ''
|
||||
if account_type not in ['Tax', 'Chargeable']:
|
||||
msgprint("'%s' is not Tax / Chargeable Account"%(d.tax_type))
|
||||
raise Exception, "Tax Account validation"
|
||||
else:
|
||||
if d.tax_type in check_list:
|
||||
msgprint("Rate is entered twice for Tax : '%s'." % (d.tax_type))
|
||||
raise Exception
|
||||
else:
|
||||
check_list.append(d.tax_type)
|
||||
|
||||
def check_for_active_boms(self, check):
|
||||
if check in ['Is Active', 'Is Purchase Item']:
|
||||
bom_mat = sql("select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 where t1.item_code ='%s' and (t1.bom_no = '' or t1.bom_no is NULL) and t2.name = t1.parent and t2.is_active = 'Yes' and t2.docstatus = 1 and t1.docstatus =1 " % self.doc.name )
|
||||
if bom_mat and bom_mat[0][0]:
|
||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(check), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
if check == 'Is Active' or ( check == 'Is Manufactured Item' and self.doc.is_sub_contracted_item != 'Yes') or (check == 'Is Sub Contracted Item' and self.doc.is_manufactured_item != 'Yes') :
|
||||
bom = sql("select name from `tabBOM` where item = '%s' and is_active ='Yes'" % cstr(self.doc.name))
|
||||
if bom and bom[0][0]:
|
||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(check), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
|
||||
def validate_barcode(self):
|
||||
if self.doc.barcode:
|
||||
duplicate = sql("select name from tabItem where barcode = %s and name != %s", (self.doc.barcode, self.doc.name))
|
||||
if duplicate:
|
||||
msgprint("Barcode: %s already used in item: %s" % (self.doc.barcode, cstr(duplicate[0][0])), raise_exception = 1)
|
||||
|
||||
def validate(self):
|
||||
fl = {'is_manufactured_item' :'Is Manufactured Item',
|
||||
'is_sub_contracted_item':'Is Sub Contracted Item',
|
||||
'is_purchase_item' :'Is Purchase Item',
|
||||
'is_pro_applicable' :'Is Pro Applicable'}
|
||||
for d in fl:
|
||||
if cstr(self.doc.fields[d]) != 'Yes':
|
||||
self.check_for_active_boms(check = fl[d])
|
||||
self.check_ref_rate_detail()
|
||||
self.fill_customer_code()
|
||||
self.check_item_tax()
|
||||
self.validate_barcode()
|
||||
if not self.doc.min_order_qty:
|
||||
self.doc.min_order_qty = 0
|
||||
self.check_non_asset_warehouse()
|
||||
|
||||
if self.doc.is_pro_applicable and self.doc.is_pro_applicable == 'Yes' and self.doc.is_manufactured_item and self.doc.is_manufactured_item != 'Yes':
|
||||
msgprint("If making Production Order is allowed then, it should also allow to make Bill of Materials. Refer Manufacturing section.")
|
||||
raise Exception
|
||||
|
||||
if self.doc.is_pro_applicable == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("As Production Order can be made for this Item, then Is Stock Item Should be 'Yes' as we maintain it's stock. Refer Manufacturing and Inventory section.", raise_exception=1)
|
||||
|
||||
if self.doc.is_stock_item == "Yes" and not self.doc.default_warehouse:
|
||||
msgprint("As we maintain stock of this item, its better to maintain default warehouse. To add default warehouse please go to 'Inventory' section. It will be fetched automatically while making Sales Order, Delivery Note, etc.. ", 1)
|
||||
|
||||
if self.doc.has_serial_no == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("'Has Serial No' can not be 'Yes' for non-stock item", raise_exception=1)
|
||||
|
||||
if self.doc.name:
|
||||
self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name')
|
||||
|
||||
def check_non_asset_warehouse(self):
|
||||
if self.doc.is_asset_item == "Yes":
|
||||
existing_qty = sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name)
|
||||
for e in existing_qty:
|
||||
msgprint("%s Units exist in Warehouse %s, which is not an Asset Warehouse." % (e[1],e[0]))
|
||||
if existing_qty:
|
||||
msgprint("Please transfer the above quantities to an asset warehouse before changing this item to an asset item.")
|
||||
self.doc.is_asset_item = 'No'
|
||||
raise Exception
|
||||
|
||||
def get_file_details(self, arg = ''):
|
||||
file = sql("select file_group, description from tabFile where name = %s", eval(arg)['file_name'], as_dict = 1)
|
||||
|
||||
ret = {
|
||||
'file_group' : file and file[0]['file_group'] or '',
|
||||
'description' : file and file[0]['description'] or ''
|
||||
|
||||
}
|
||||
return ret
|
||||
|
||||
def check_if_sle_exists(self):
|
||||
"""
|
||||
checks if any stock ledger entry exists for this item
|
||||
"""
|
||||
|
||||
sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
|
||||
return sle and 'exists' or 'not exists'
|
||||
|
||||
def on_rename(self,newdn,olddn):
|
||||
sql("update tabItem set item_code = %s where name = %s", (newdn, olddn))
|
||||
|
||||
def delete_web_cache(self, page_name):
|
||||
import website.web_cache
|
||||
website.web_cache.delete_cache(page_name)
|
||||
|
||||
def clear_web_cache(self):
|
||||
if hasattr(self, 'old_page_name') and self.old_page_name and \
|
||||
self.doc.page_name != self.old_page_name:
|
||||
self.delete_web_cache(self.doc.page_name)
|
||||
|
||||
if self.doc.show_in_website:
|
||||
import website.web_cache
|
||||
website.web_cache.create_cache(self.doc.page_name, self.doc.doctype, self.doc.name)
|
||||
website.web_cache.clear_cache(self.doc.page_name, self.doc.doctype, self.doc.name)
|
||||
else:
|
||||
self.delete_web_cache(self.doc.page_name)
|
||||
|
||||
def update_page_name(self):
|
||||
import website.utils
|
||||
|
||||
# if same name, do not repeat twice
|
||||
if self.doc.name == self.doc.item_name or not self.doc.item_name:
|
||||
page_name = self.doc.name
|
||||
else:
|
||||
page_name = self.doc.name + " " + self.doc.item_name
|
||||
|
||||
self.doc.page_name = website.utils.page_name(page_name)
|
||||
|
||||
webnotes.conn.set_value('Item', self.doc.name, 'page_name', self.doc.page_name)
|
||||
|
||||
# no need to check for uniqueness, as name is unique
|
||||
|
||||
def prepare_template_args(self):
|
||||
import markdown2
|
||||
self.doc.web_description_html = markdown2.markdown(self.doc.description or '',
|
||||
extras=["wiki-tables"])
|
||||
1014
stock/doctype/item/item.txt
Normal file
1014
stock/doctype/item/item.txt
Normal file
File diff suppressed because it is too large
Load Diff
28
stock/doctype/item/item_list.js
Normal file
28
stock/doctype/item/item_list.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// render
|
||||
wn.doclistviews['Item'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabItem`.item_name",
|
||||
"`tabItem`.description",
|
||||
]);
|
||||
this.stats = this.stats.concat(['default_warehouse', 'brand']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
data.description = repl("%(item_name)s | %(description)s", data);
|
||||
if(data.description && data.description.length > 50) {
|
||||
data.description = '<span title="'+data.description+'">' +
|
||||
data.description.substr(0,50) + '...</span>';
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '20%', content:'name'},
|
||||
{width: '60%', content:'description+tags', css: {'color': '#222'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
||||
]
|
||||
});
|
||||
79
stock/doctype/item/test_item.py
Normal file
79
stock/doctype/item/test_item.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# 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 unittest
|
||||
import webnotes
|
||||
import copy
|
||||
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.doc import Document
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes.utils import flt
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
|
||||
class TestItem(unittest.TestCase):
|
||||
def setUp(self):
|
||||
webnotes.conn.begin()
|
||||
|
||||
def tearDown(self):
|
||||
webnotes.conn.rollback()
|
||||
|
||||
def testInsert(self):
|
||||
d = DocList()
|
||||
|
||||
count_before = flt(sql("select count(*) from tab"+_doctype)[0][0])
|
||||
if docok:
|
||||
for i in docok:
|
||||
d.doc = i
|
||||
d.children = None
|
||||
d.doc.fields['__islocal']=1
|
||||
d.save(1)
|
||||
count_after = flt(sql("select count(*) from tab"+_doctype)[0][0])
|
||||
self.assertTrue(count_before+len(docok)==count_after)
|
||||
|
||||
def testFailAssert(self):
|
||||
if docnotok:
|
||||
with self.assertRaises(Exception) as context:
|
||||
d = DocList()
|
||||
d.doc = docnotok[0]
|
||||
d.children = None
|
||||
d.doc.fields['__islocal']=1
|
||||
d.save(1)
|
||||
|
||||
# Test Data
|
||||
|
||||
tabOK = [
|
||||
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Ink', 'default_warehouse': None, 'item_name': 'Gel Ink', 'item_group': 'Ink', 'item_code': 'GELINK', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'},
|
||||
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Refill', 'default_warehouse': None, 'item_name': 'Gel Refill', 'item_group': 'Refill', 'item_code': 'GELREF', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'},
|
||||
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Pen', 'default_warehouse': None, 'item_name': 'Gel Pen', 'item_group': 'Pen', 'item_code': 'GELPEN', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}
|
||||
]
|
||||
|
||||
tabNotOK = [
|
||||
{'is_purchase_item': None, 'is_pro_applicable': None, 'is_manufactured_item': None, 'description': 'F Ink', 'default_warehouse': None, 'item_name': 'F Ink', 'item_group': 'F Ink', 'item_code': None, 'is_sub_contracted_item': None, 'is_stock_item': 'No', 'stock_uom': 'Nos', 'docstatus': '0'}
|
||||
]
|
||||
|
||||
_doctype = 'Item'
|
||||
|
||||
for i in tabOK: i['doctype']=_doctype
|
||||
for i in tabNotOK: i['doctype']=_doctype
|
||||
|
||||
docok = [Document(fielddata=r) for r in tabOK]
|
||||
docnotok = [Document(fielddata=r) for r in tabNotOK]
|
||||
|
||||
|
||||
1
stock/doctype/item_customer_detail/__init__.py
Normal file
1
stock/doctype/item_customer_detail/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
71
stock/doctype/item_customer_detail/item_customer_detail.txt
Normal file
71
stock/doctype/item_customer_detail/item_customer_detail.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
# DocType, Item Customer Detail
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:33',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:33',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'ITEMCUST/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'description': u'For the convenience of customers, these codes can be used in print formats like Invoices and Delivery Notes',
|
||||
'doctype': 'DocType',
|
||||
'in_create': 1,
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'read_only': 0,
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 7
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'in_filter': 1,
|
||||
'name': '__common__',
|
||||
'parent': u'Item Customer Detail',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocType, Item Customer Detail
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Item Customer Detail'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer Name',
|
||||
'oldfieldname': u'price_list_name',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'Customer',
|
||||
'width': u'180px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_code',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Ref Code',
|
||||
'oldfieldname': u'ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'width': u'120px'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/item_price/__init__.py
Normal file
1
stock/doctype/item_price/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
82
stock/doctype/item_price/item_price.txt
Normal file
82
stock/doctype/item_price/item_price.txt
Normal file
@@ -0,0 +1,82 @@
|
||||
# DocType, Item Price
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:36',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:36',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'RFD/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'in_create': 1,
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'read_only': 0,
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 3
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'in_filter': 1,
|
||||
'name': '__common__',
|
||||
'parent': u'Item Price',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocType, Item Price
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Item Price'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'price_list_name',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Price List Name',
|
||||
'oldfieldname': u'price_list_name',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Price List',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Ref Rate',
|
||||
'oldfieldname': u'ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_currency',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Currency',
|
||||
'oldfieldname': u'ref_currency',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Currency',
|
||||
'reqd': 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,64 @@
|
||||
# DocType, Item Quality Inspection Parameter
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:33',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:33',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'IISD/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'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',
|
||||
'fieldtype': u'Data',
|
||||
'name': '__common__',
|
||||
'oldfieldtype': u'Data',
|
||||
'parent': u'Item Quality Inspection Parameter',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Item Quality Inspection Parameter
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Item Quality Inspection Parameter'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'specification',
|
||||
'in_filter': 0,
|
||||
'label': u'Parameter',
|
||||
'oldfieldname': u'specification',
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'width': u'200px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'value',
|
||||
'label': u'Acceptance Criteria',
|
||||
'oldfieldname': u'value'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/item_supplier/__init__.py
Normal file
1
stock/doctype/item_supplier/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
58
stock/doctype/item_supplier/item_supplier.txt
Normal file
58
stock/doctype/item_supplier/item_supplier.txt
Normal file
@@ -0,0 +1,58 @@
|
||||
# DocType, Item Supplier
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:33',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:33',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'show_in_menu': 0,
|
||||
'version': 3
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Item Supplier',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Item Supplier
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Item Supplier'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Supplier',
|
||||
'options': u'Supplier'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier_part_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Supplier Part Number',
|
||||
'width': u'200px'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/item_tax/__init__.py
Normal file
1
stock/doctype/item_tax/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
64
stock/doctype/item_tax/item_tax.txt
Normal file
64
stock/doctype/item_tax/item_tax.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
# DocType, Item Tax
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:33',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:33',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Item Tax',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Item Tax
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Item Tax'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'tax_type',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Tax',
|
||||
'oldfieldname': u'tax_type',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Account',
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'tax_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Tax Rate',
|
||||
'oldfieldname': u'tax_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'reqd': 0
|
||||
}
|
||||
]
|
||||
1
stock/doctype/landed_cost_item/__init__.py
Normal file
1
stock/doctype/landed_cost_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
76
stock/doctype/landed_cost_item/landed_cost_item.txt
Normal file
76
stock/doctype/landed_cost_item/landed_cost_item.txt
Normal file
@@ -0,0 +1,76 @@
|
||||
# DocType, Landed Cost Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-03 11:00:55',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-04 13:02:26',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'wasim@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'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'Landed Cost Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocType, Landed Cost Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Landed Cost Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'account_head',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Account Head',
|
||||
'oldfieldname': u'account_head',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Account',
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Data',
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount',
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/landed_cost_master/__init__.py
Normal file
1
stock/doctype/landed_cost_master/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
30
stock/doctype/landed_cost_master/landed_cost_master.js
Normal file
30
stock/doctype/landed_cost_master/landed_cost_master.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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) {
|
||||
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.landed_cost.grid.get_field('account_head').get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND (tabAccount.account_type = "Tax" OR tabAccount.account_type = "Chargeable" or (tabAccount.is_pl_account = "Yes" and tabAccount.debit_or_credit = "Debit")) AND tabAccount.name LIKE "%s"';
|
||||
}
|
||||
150
stock/doctype/landed_cost_master/landed_cost_master.txt
Normal file
150
stock/doctype/landed_cost_master/landed_cost_master.txt
Normal file
@@ -0,0 +1,150 @@
|
||||
# DocType, Landed Cost Master
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-07-03 13:29:45',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-09-17 10:53:26',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1309508838',
|
||||
'autoname': u'field:title',
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Stock',
|
||||
u'name': u'__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Landed Cost Master',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Landed Cost Master',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Landed Cost Master
|
||||
{
|
||||
u'doctype': u'DocType',
|
||||
u'name': u'Landed Cost Master'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
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
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'title',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Title',
|
||||
'oldfieldname': u'title',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'landed_cost_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Landed Cost Items',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'landed_cost',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Landed Cost',
|
||||
'oldfieldname': u'landed_cost',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Landed Cost Master Detail',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Purchase Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Purchase User',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Purchase User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Purchase Manager'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/landed_cost_master_detail/__init__.py
Normal file
1
stock/doctype/landed_cost_master_detail/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,61 @@
|
||||
# DocType, Landed Cost Master Detail
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-03 11:00:55',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-04 13:02:35',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'oldfieldtype': u'Data',
|
||||
'parent': u'Landed Cost Master Detail',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Landed Cost Master Detail
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Landed Cost Master Detail'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'account_head',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Account Head',
|
||||
'oldfieldname': u'account_head',
|
||||
'options': u'Account'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'width': u'300px'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/landed_cost_purchase_receipt/__init__.py
Normal file
1
stock/doctype/landed_cost_purchase_receipt/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,65 @@
|
||||
# DocType, Landed Cost Purchase Receipt
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:34',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:34',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'wasim@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 5
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Landed Cost Purchase Receipt',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Landed Cost Purchase Receipt
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Landed Cost Purchase Receipt'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_receipt',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Purchase Receipt',
|
||||
'oldfieldname': u'purchase_receipt_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Purchase Receipt',
|
||||
'width': u'220px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'select_pr',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Select PR',
|
||||
'oldfieldname': u'include_in_landed_cost',
|
||||
'oldfieldtype': u'Check',
|
||||
'width': u'120px'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/landed_cost_wizard/__init__.py
Normal file
1
stock/doctype/landed_cost_wizard/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
24
stock/doctype/landed_cost_wizard/landed_cost_wizard.js
Normal file
24
stock/doctype/landed_cost_wizard/landed_cost_wizard.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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.onload = function(doc, cdt, cdn) {
|
||||
if(!doc.currency){doc.currency = sys_defaults.currency;}
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['landed_cost_details'].grid.get_field("account_head").get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND (tabAccount.account_type = "Tax" OR tabAccount.account_type = "Chargeable" or (tabAccount.is_pl_account = "Yes" and tabAccount.debit_or_credit = "Debit")) AND tabAccount.name LIKE "%s"';
|
||||
}
|
||||
255
stock/doctype/landed_cost_wizard/landed_cost_wizard.py
Normal file
255
stock/doctype/landed_cost_wizard/landed_cost_wizard.py
Normal file
@@ -0,0 +1,255 @@
|
||||
# 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
|
||||
from webnotes.utils import cint, cstr, flt
|
||||
from webnotes.model.doc import addchild, getchildren
|
||||
from webnotes.model.doclist import getlist
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes import msgprint
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.prwise_cost = {}
|
||||
|
||||
def check_mandatory(self):
|
||||
""" Check mandatory fields """
|
||||
if not self.doc.from_pr_date or not self.doc.to_pr_date:
|
||||
msgprint("Please enter From and To PR Date", raise_exception=1)
|
||||
|
||||
if not self.doc.currency:
|
||||
msgprint("Please enter Currency.", raise_exception=1)
|
||||
|
||||
|
||||
def get_purchase_receipts(self):
|
||||
""" Get purchase receipts for given period """
|
||||
|
||||
self.doclist = self.doc.clear_table(self.doclist,'lc_pr_details',1)
|
||||
self.check_mandatory()
|
||||
|
||||
pr = sql("select name from `tabPurchase Receipt` where docstatus = 1 and posting_date >= '%s' and posting_date <= '%s' and currency = '%s' order by name " % (self.doc.from_pr_date, self.doc.to_pr_date, self.doc.currency), as_dict = 1)
|
||||
if len(pr)>200:
|
||||
msgprint("Please enter date of shorter duration as there are too many purchase receipt, hence it cannot be loaded.", raise_exception=1)
|
||||
|
||||
for i in pr:
|
||||
ch = addchild(self.doc, 'lc_pr_details', 'Landed Cost Purchase Receipt', 1, self.doclist)
|
||||
ch.purchase_receipt = i and i['name'] or ''
|
||||
ch.save()
|
||||
|
||||
|
||||
def get_landed_cost_master_details(self):
|
||||
""" pull details from landed cost master"""
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'landed_cost_details')
|
||||
idx = 0
|
||||
landed_cost = sql("select account_head, description from `tabLanded Cost Master Detail` where parent=%s", (self.doc.landed_cost), as_dict = 1)
|
||||
for cost in landed_cost:
|
||||
lct = addchild(self.doc, 'landed_cost_details', 'Landed Cost Item', 1, self.doclist)
|
||||
lct.account_head = cost['account_head']
|
||||
lct.description = cost['description']
|
||||
|
||||
|
||||
def get_selected_pr(self):
|
||||
""" Get selected purchase receipt no """
|
||||
self.selected_pr = [d.purchase_receipt for d in getlist(self.doclist, 'lc_pr_details') if d.select_pr]
|
||||
if not self.selected_pr:
|
||||
msgprint("Please select atleast one PR to proceed.", raise_exception=1)
|
||||
|
||||
def validate_selected_pr(self):
|
||||
"""Validate selected PR as submitted"""
|
||||
invalid_pr = sql("SELECT name FROM `tabPurchase Receipt` WHERE docstatus != 1 and name in (%s)" % ("'" + "', '".join(self.selected_pr) + "'"))
|
||||
if invalid_pr:
|
||||
msgprint("Selected purchase receipts must be submitted. Following PR are not submitted: %s" % invalid_pr, raise_exception=1)
|
||||
|
||||
|
||||
def get_total_amt(self):
|
||||
""" Get sum of net total of all selected PR"""
|
||||
return sql("SELECT SUM(net_total) FROM `tabPurchase Receipt` WHERE name in (%s)" % ("'" + "', '".join(self.selected_pr) + "'"))[0][0]
|
||||
|
||||
|
||||
def add_charges_in_pr(self):
|
||||
""" Add additional charges in selected pr proportionately"""
|
||||
total_amt = self.get_total_amt()
|
||||
|
||||
for pr in self.selected_pr:
|
||||
pr_obj = get_obj('Purchase Receipt', pr, with_children = 1)
|
||||
cumulative_grand_total = flt(pr_obj.doc.grand_total)
|
||||
|
||||
for lc in getlist(self.doclist, 'landed_cost_details'):
|
||||
amt = flt(lc.amount) * flt(pr_obj.doc.net_total)/ flt(total_amt)
|
||||
self.prwise_cost[pr] = self.prwise_cost.get(pr, 0) + amt
|
||||
cumulative_grand_total += amt
|
||||
|
||||
pr_oc_row = sql("select name from `tabPurchase Taxes and Charges` where parent = %s and category = 'For Valuation' and add_deduct_tax = 'Add' and charge_type = 'Actual' and account_head = %s",(pr, lc.account_head))
|
||||
if not pr_oc_row: # add if not exists
|
||||
ch = addchild(pr_obj.doc, 'purchase_tax_details', 'Purchase Taxes and Charges', 1)
|
||||
ch.category = 'For Valuation'
|
||||
ch.add_deduct_tax = 'Add'
|
||||
ch.charge_type = 'Actual'
|
||||
ch.description = lc.description
|
||||
ch.account_head = lc.account_head
|
||||
ch.rate = amt
|
||||
ch.tax_amount = amt
|
||||
ch.total = cumulative_grand_total
|
||||
ch.docstatus = 1
|
||||
ch.idx = 500 # add at the end
|
||||
ch.save(1)
|
||||
else: # overwrite if exists
|
||||
sql("update `tabPurchase Taxes and Charges` set rate = %s, tax_amount = %s where name = %s and parent = %s ", (amt, amt, pr_oc_row[0][0], pr))
|
||||
|
||||
|
||||
def reset_other_charges(self, pr_obj):
|
||||
""" Reset all calculated values to zero"""
|
||||
for t in getlist(pr_obj.doclist, 'purchase_tax_details'):
|
||||
t.total_tax_amount = 0;
|
||||
t.total_amount = 0;
|
||||
t.tax_amount = 0;
|
||||
t.total = 0;
|
||||
t.save()
|
||||
|
||||
|
||||
def cal_charges_and_item_tax_amt(self):
|
||||
""" Re-calculates other charges values and itemwise tax amount for getting valuation rate"""
|
||||
import json
|
||||
for pr in self.selected_pr:
|
||||
obj = get_obj('Purchase Receipt', pr, with_children = 1)
|
||||
total = 0
|
||||
self.reset_other_charges(obj)
|
||||
|
||||
for prd in getlist(obj.doclist, 'purchase_receipt_details'):
|
||||
prev_total, item_tax = flt(prd.amount), 0
|
||||
total += flt(prd.qty) * flt(prd.purchase_rate)
|
||||
|
||||
try:
|
||||
item_tax_rate = prd.item_tax_rate and json.loads(prd.item_tax_rate) or {}
|
||||
except ValueError:
|
||||
item_tax_rate = prd.item_tax_rate and eval(prd.item_tax_rate) or {}
|
||||
|
||||
|
||||
ocd = getlist(obj.doclist, 'purchase_tax_details')
|
||||
# calculate tax for other charges
|
||||
for oc in range(len(ocd)):
|
||||
# Get rate : consider if diff for this item
|
||||
if item_tax_rate.get(ocd[oc].account_head) and ocd[oc].charge_type != 'Actual':
|
||||
rate = item_tax_rate[ocd[oc].account_head]
|
||||
else:
|
||||
rate = flt(ocd[oc].rate)
|
||||
|
||||
tax_amount = self.cal_tax(ocd, prd, rate, obj.doc.net_total, oc)
|
||||
total, prev_total, item_tax = self.add_deduct_taxes(ocd, oc, tax_amount, total, prev_total, item_tax)
|
||||
|
||||
prd.item_tax_amount = flt(item_tax)
|
||||
prd.save()
|
||||
obj.doc.save()
|
||||
|
||||
|
||||
def cal_tax(self, ocd, prd, rate, net_total, oc):
|
||||
""" Calculates tax amount for one item"""
|
||||
tax_amount = 0
|
||||
if ocd[oc].charge_type == 'Actual':
|
||||
tax_amount = flt(rate) * flt(prd.amount) / flt(net_total)
|
||||
elif ocd[oc].charge_type == 'On Net Total':
|
||||
tax_amount = flt(rate) * flt(prd.amount) / 100
|
||||
elif ocd[oc].charge_type == 'On Previous Row Amount':
|
||||
row_no = cstr(ocd[oc].row_id)
|
||||
row = row_no.split("+")
|
||||
for r in range(0, len(row)):
|
||||
id = cint(row[r])
|
||||
tax_amount += flt((flt(rate) * flt(ocd[id-1].total_amount) / 100))
|
||||
row_id = row_no.find("/")
|
||||
if row_id != -1:
|
||||
rate = ''
|
||||
row = (row_no).split("/")
|
||||
id1 = cint(row[0])
|
||||
id2 = cint(row[1])
|
||||
tax_amount = flt(flt(ocd[id1-1].total_amount) / flt(ocd[id2-1].total_amount))
|
||||
elif ocd[oc].charge_type == 'On Previous Row Total':
|
||||
row = cint(ocd[oc].row_id)
|
||||
if ocd[row-1].add_deduct_tax == 'Add':
|
||||
tax_amount = flt(rate) * (flt(ocd[row-1].total_tax_amount)+flt(ocd[row-1].total_amount)) / 100
|
||||
elif ocd[row-1].add_deduct_tax == 'Deduct':
|
||||
tax_amount = flt(rate) * (flt(ocd[row-1].total_tax_amount)-flt(ocd[row-1].total_amount)) / 100
|
||||
|
||||
return tax_amount
|
||||
|
||||
def add_deduct_taxes(self, ocd, oc, tax_amount, total, prev_total, item_tax):
|
||||
"""Calculates other charges values"""
|
||||
add_ded = ocd[oc].add_deduct_tax == 'Add' and 1 or ocd[oc].add_or_deduct == 'Deduct' and -1
|
||||
ocd[oc].total_amount = flt(tax_amount)
|
||||
ocd[oc].total_tax_amount = flt(prev_total)
|
||||
ocd[oc].tax_amount += flt(tax_amount)
|
||||
|
||||
total_amount = flt(ocd[oc].tax_amount)
|
||||
total_tax_amount = flt(ocd[oc].total_tax_amount) + (add_ded * flt(total_amount))
|
||||
|
||||
if ocd[oc].category != "For Valuation":
|
||||
prev_total += add_ded * flt(ocd[oc].total_amount)
|
||||
total += add_ded * flt(ocd[oc].tax_amount)
|
||||
ocd[oc].total = total
|
||||
else:
|
||||
prev_total = prev_total
|
||||
ocd[oc].total = flt(total)
|
||||
ocd[oc].save()
|
||||
|
||||
if ocd[oc].category != "For Total":
|
||||
item_tax += add_ded * ocd[oc].total_amount
|
||||
|
||||
return total, prev_total, item_tax
|
||||
|
||||
|
||||
def update_sle(self):
|
||||
""" Recalculate valuation rate in all sle after pr posting date"""
|
||||
for pr in self.selected_pr:
|
||||
pr_obj = get_obj('Purchase Receipt', pr, with_children = 1)
|
||||
|
||||
for d in getlist(pr_obj.doclist, 'purchase_receipt_details'):
|
||||
if flt(d.qty):
|
||||
d.valuation_rate = (flt(d.purchase_rate) + (flt(d.rm_supp_cost)/flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
|
||||
d.save()
|
||||
self.update_serial_no(d.serial_no, d.valuation_rate)
|
||||
sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
|
||||
|
||||
bin = sql("select t1.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1" % d.name)
|
||||
|
||||
# update valuation rate after pr posting date
|
||||
if bin and bin[0][0]:
|
||||
obj = get_obj('Bin', bin[0][0]).update_entries_after(bin[0][1], bin[0][2])
|
||||
|
||||
|
||||
def update_serial_no(self, sr_no, rate):
|
||||
""" update valuation rate in serial no"""
|
||||
sr_no = cstr(sr_no).split('\n')
|
||||
for d in sr_no:
|
||||
sql("update `tabSerial No` set purchase_rate = %s where name = %s", (rate, d))
|
||||
|
||||
|
||||
def update_landed_cost(self):
|
||||
"""
|
||||
Add extra cost and recalculate all values in pr,
|
||||
Recalculate valuation rate in all sle after pr posting date
|
||||
"""
|
||||
self.get_selected_pr()
|
||||
self.validate_selected_pr()
|
||||
self.add_charges_in_pr()
|
||||
self.cal_charges_and_item_tax_amt()
|
||||
self.update_sle()
|
||||
msgprint("Landed Cost updated successfully")
|
||||
219
stock/doctype/landed_cost_wizard/landed_cost_wizard.txt
Normal file
219
stock/doctype/landed_cost_wizard/landed_cost_wizard.txt
Normal file
@@ -0,0 +1,219 @@
|
||||
# DocType, Landed Cost Wizard
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-07-03 13:29:45',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-09-17 10:54:21',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'wasim@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1321441191',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
u'doctype': u'DocType',
|
||||
'issingle': 1,
|
||||
'module': u'Stock',
|
||||
u'name': u'__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 1,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Landed Cost Wizard',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Landed Cost Wizard',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Landed Cost Wizard
|
||||
{
|
||||
u'doctype': u'DocType',
|
||||
u'name': u'Landed Cost Wizard'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'process',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Process',
|
||||
'options': u'<div class="field_description"><b>Process:</b><br>1. Fetch and select Purchase Receipt<br>2. Enter extra costs<br>3. Click on Update Landed Cost button<br> 4. Cost will be added into other charges table of selected PR proportionately based on net total<br>5. Item Valuation Rate will be recalculated</div>'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'section_break0',
|
||||
'fieldtype': u'Section Break',
|
||||
'options': u'Simple'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'from_pr_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'From PR Date',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'to_pr_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'To PR Date',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'currency',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Currency',
|
||||
'options': u'link:Currency',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'get_purchase_receipt',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Get Purchase Receipt',
|
||||
'options': u'get_purchase_receipts'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'lc_pr_details',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Landed Cost Purchase Receipts',
|
||||
'options': u'Landed Cost Purchase Receipt'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'section_break1',
|
||||
'fieldtype': u'Section Break',
|
||||
'options': u'Simple'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'landed_cost',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Select Landed Cost Items Master',
|
||||
'options': u'Landed Cost Master'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'get_details',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Get Details',
|
||||
'options': u'get_landed_cost_master_details'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'landed_cost_details',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Landed Cost Items',
|
||||
'options': u'Landed Cost Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'update_pr',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Update PR',
|
||||
'options': u'update_landed_cost'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Purchase Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Purchase User',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Purchase User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Purchase Manager'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/packing_slip/__init__.py
Normal file
1
stock/doctype/packing_slip/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
149
stock/doctype/packing_slip/packing_slip.js
Normal file
149
stock/doctype/packing_slip/packing_slip.js
Normal file
@@ -0,0 +1,149 @@
|
||||
// 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.fields_dict['delivery_note'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name FROM `tabDelivery Note` WHERE docstatus=0 AND %(key)s LIKE "%s"';
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
||||
console.log(doc.delivery_note);
|
||||
var query = 'SELECT name, description FROM `tabItem` WHERE name IN ( \
|
||||
SELECT item_code FROM `tabDelivery Note Item` dnd \
|
||||
WHERE parent="' + doc.delivery_note + '" AND IFNULL(qty, 0) > IFNULL(packed_qty, 0)) AND %(key)s LIKE "%s" LIMIT 50';
|
||||
console.log(query);
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
// Fetch item details
|
||||
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
|
||||
if(locals[cdt][cdn].item_code) {
|
||||
$c_obj(make_doclist(cdt, cdn), 'get_item_details', doc.delivery_note, function(r, rt) {
|
||||
if(r.exc) {
|
||||
msgprint(r.exc);
|
||||
} else {
|
||||
refresh_field('item_details');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(doc.delivery_note) {
|
||||
var ps_detail = getchildren('Packing Slip Item', doc.name, 'item_details');
|
||||
if(!(flt(ps_detail[0].net_weight) && cstr(ps_detail[0].weight_uom))) {
|
||||
cur_frm.cscript.update_item_details(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, dt, dn) {
|
||||
if(!doc.amended_from) {
|
||||
hide_field('misc_details');
|
||||
} else {
|
||||
unhide_field('misc_details');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.update_item_details = function(doc) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name), 'update_item_details', '', function(r, rt) {
|
||||
if(r.exc) {
|
||||
msgprint(r.exc);
|
||||
} else {
|
||||
refresh_many(['item_details', 'naming_series', 'from_case_no', 'to_case_no'])
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.validate_case_nos(doc);
|
||||
cur_frm.cscript.validate_calculate_item_details(doc);
|
||||
}
|
||||
|
||||
|
||||
// To Case No. cannot be less than From Case No.
|
||||
cur_frm.cscript.validate_case_nos = function(doc) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if(cint(doc.from_case_no)==0) {
|
||||
msgprint("Case No. cannot be 0")
|
||||
validated = false;
|
||||
} else if(!cint(doc.to_case_no)) {
|
||||
doc.to_case_no = doc.from_case_no;
|
||||
refresh_field('to_case_no');
|
||||
} else if(cint(doc.to_case_no) < cint(doc.from_case_no)) {
|
||||
msgprint("'To Case No.' cannot be less than 'From Case No.'");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.validate_calculate_item_details = function(doc) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var ps_detail = getchildren('Packing Slip Item', doc.name, 'item_details');
|
||||
|
||||
cur_frm.cscript.validate_duplicate_items(doc, ps_detail);
|
||||
cur_frm.cscript.calc_net_total_pkg(doc, ps_detail);
|
||||
}
|
||||
|
||||
|
||||
// Do not allow duplicate items i.e. items with same item_code
|
||||
// Also check for 0 qty
|
||||
cur_frm.cscript.validate_duplicate_items = function(doc, ps_detail) {
|
||||
for(var i=0; i<ps_detail.length; i++) {
|
||||
for(var j=0; j<ps_detail.length; j++) {
|
||||
if(i!=j && ps_detail[i].item_code==ps_detail[j].item_code) {
|
||||
msgprint("You have entered duplicate items. Please rectify and try again.");
|
||||
validated = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(flt(ps_detail[i].qty)<=0) {
|
||||
msgprint("Invalid quantity specified for item " + ps_detail[i].item_code +
|
||||
". Quantity should be greater than 0.");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate Net Weight of Package
|
||||
cur_frm.cscript.calc_net_total_pkg = function(doc, ps_detail) {
|
||||
var net_weight_pkg = 0;
|
||||
doc.net_weight_uom = ps_detail?ps_detail[0].weight_uom:'';
|
||||
doc.gross_weight_uom = doc.net_weight_uom;
|
||||
|
||||
for(var i=0; i<ps_detail.length; i++) {
|
||||
var item = ps_detail[i];
|
||||
if(item.weight_uom != doc.net_weight_uom) {
|
||||
msgprint("Different UOM for items will lead to incorrect \
|
||||
(Total) Net Weight value. Make sure that Net Weight of each item is \
|
||||
in the same UOM.")
|
||||
validated = false;
|
||||
}
|
||||
net_weight_pkg += flt(item.net_weight) * flt(item.qty);
|
||||
}
|
||||
|
||||
doc.net_weight_pkg = roundNumber(net_weight_pkg, 2);
|
||||
if(!flt(doc.gross_weight_pkg)) {
|
||||
doc.gross_weight_pkg = doc.net_weight_pkg
|
||||
}
|
||||
refresh_many(['net_weight_pkg', 'net_weight_uom', 'gross_weight_uom', 'gross_weight_pkg']);
|
||||
}
|
||||
|
||||
191
stock/doctype/packing_slip/packing_slip.py
Normal file
191
stock/doctype/packing_slip/packing_slip.py
Normal file
@@ -0,0 +1,191 @@
|
||||
# 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
|
||||
from webnotes.utils import flt, cint
|
||||
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
|
||||
def validate(self):
|
||||
"""
|
||||
* Validate existence of submitted Delivery Note
|
||||
* Case nos do not overlap
|
||||
* Check if packed qty doesn't exceed actual qty of delivery note
|
||||
|
||||
It is necessary to validate case nos before checking quantity
|
||||
"""
|
||||
self.validate_delivery_note()
|
||||
self.validate_case_nos()
|
||||
self.validate_qty()
|
||||
|
||||
|
||||
def validate_delivery_note(self):
|
||||
"""
|
||||
Validates if delivery note has status as submitted
|
||||
"""
|
||||
res = webnotes.conn.sql("""\
|
||||
SELECT docstatus FROM `tabDelivery Note`
|
||||
WHERE name=%(delivery_note)s
|
||||
""", self.doc.fields)
|
||||
|
||||
if not(res and res[0][0]==0):
|
||||
webnotes.msgprint("""Invalid Delivery Note. Delivery Note should exist
|
||||
and should be in draft state. Please rectify and try again.""",
|
||||
raise_exception=1)
|
||||
|
||||
|
||||
def validate_case_nos(self):
|
||||
"""
|
||||
Validate if case nos overlap
|
||||
If they do, recommend next case no.
|
||||
"""
|
||||
res = webnotes.conn.sql("""\
|
||||
SELECT name FROM `tabPacking Slip`
|
||||
WHERE delivery_note = %(delivery_note)s AND docstatus = 1 AND
|
||||
(from_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s
|
||||
OR to_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s)\
|
||||
""", self.doc.fields)
|
||||
|
||||
if res:
|
||||
webnotes.msgprint("""Case No(s). already in use. Please rectify and try again.
|
||||
Recommended <b>From Case No. = %s</b>""" % self.get_recommended_case_no(),
|
||||
raise_exception=1)
|
||||
|
||||
|
||||
def validate_qty(self):
|
||||
"""
|
||||
Check packed qty across packing slips and delivery note
|
||||
"""
|
||||
# Get Delivery Note Items, Item Quantity Dict and No. of Cases for this Packing slip
|
||||
dn_details, ps_item_qty, no_of_cases = self.get_details_for_packing()
|
||||
|
||||
for item in dn_details:
|
||||
new_packed_qty = (flt(ps_item_qty[item['item_code']]) * no_of_cases) + flt(item['packed_qty'])
|
||||
if new_packed_qty > flt(item['qty']):
|
||||
self.recommend_new_qty(item, ps_item_qty, no_of_cases)
|
||||
|
||||
|
||||
def get_details_for_packing(self):
|
||||
"""
|
||||
Returns
|
||||
* 'Delivery Note Items' query result as a list of dict
|
||||
* Item Quantity dict of current packing slip doc
|
||||
* No. of Cases of this packing slip
|
||||
"""
|
||||
item_codes = ", ".join([('"' + d.item_code + '"') for d in
|
||||
self.doclist])
|
||||
|
||||
if not item_codes: webnotes.msgprint("No Items to Pack",
|
||||
raise_exception=1)
|
||||
|
||||
res = webnotes.conn.sql("""\
|
||||
SELECT item_code, IFNULL(SUM(qty), 0) as qty, IFNULL(packed_qty, 0) as packed_qty, stock_uom
|
||||
FROM `tabDelivery Note Item`
|
||||
WHERE parent = "%s" AND item_code IN (%s)
|
||||
GROUP BY item_code""" % (self.doc.delivery_note, item_codes),
|
||||
as_dict=1)
|
||||
|
||||
ps_item_qty = dict([[d.item_code, d.qty] for d in self.doclist])
|
||||
|
||||
no_of_cases = cint(self.doc.to_case_no) - cint(self.doc.from_case_no) + 1
|
||||
|
||||
return res, ps_item_qty, no_of_cases
|
||||
|
||||
|
||||
def recommend_new_qty(self, item, ps_item_qty, no_of_cases):
|
||||
"""
|
||||
Recommend a new quantity and raise a validation exception
|
||||
"""
|
||||
item['recommended_qty'] = (flt(item['qty']) - flt(item['packed_qty'])) / no_of_cases
|
||||
item['specified_qty'] = flt(ps_item_qty[item['item_code']])
|
||||
|
||||
webnotes.msgprint("""\
|
||||
Invalid Quantity specified (%(specified_qty)s %(stock_uom)s).
|
||||
%(packed_qty)s out of %(qty)s %(stock_uom)s already packed for %(item_code)s.
|
||||
<b>Recommended quantity for %(item_code)s = %(recommended_qty)s \
|
||||
%(stock_uom)s</b>""" % item, raise_exception=1)
|
||||
|
||||
|
||||
def on_submit(self):
|
||||
"""
|
||||
* Update packed qty for all items
|
||||
"""
|
||||
self.update_packed_qty(event='submit')
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
"""
|
||||
* Update packed qty for all items
|
||||
"""
|
||||
self.update_packed_qty(event='cancel')
|
||||
|
||||
|
||||
def update_packed_qty(self, event=''):
|
||||
"""
|
||||
Updates packed qty for all items
|
||||
"""
|
||||
if event not in ['submit', 'cancel']:
|
||||
raise Exception('update_packed_quantity can only be called on submit or cancel')
|
||||
|
||||
# Get Delivery Note Items, Item Quantity Dict and No. of Cases for this Packing slip
|
||||
dn_details, ps_item_qty, no_of_cases = self.get_details_for_packing()
|
||||
|
||||
for item in dn_details:
|
||||
if event=='submit':
|
||||
new_packed_qty = flt(item['packed_qty']) + (flt(ps_item_qty[item['item_code']]) * no_of_cases)
|
||||
|
||||
elif event=='cancel':
|
||||
new_packed_qty = flt(item['packed_qty']) - (flt(ps_item_qty[item['item_code']]) * no_of_cases)
|
||||
|
||||
if (new_packed_qty < 0) or (new_packed_qty > flt(item['qty'])):
|
||||
webnotes.msgprint("Invalid new packed quantity for item %s. \
|
||||
Please try again or contact support@erpnext.com" % item['item_code'], raise_exception=1)
|
||||
|
||||
webnotes.conn.sql("""\
|
||||
UPDATE `tabDelivery Note Item`
|
||||
SET packed_qty = %s
|
||||
WHERE parent = %s AND item_code = %s""",
|
||||
(new_packed_qty, self.doc.delivery_note, item['item_code']))
|
||||
|
||||
|
||||
def update_item_details(self):
|
||||
"""
|
||||
Fill empty columns in Packing Slip Item
|
||||
"""
|
||||
self.doc.from_case_no = self.get_recommended_case_no()
|
||||
|
||||
from webnotes.model.code import get_obj
|
||||
for d in self.doclist:
|
||||
psd_obj = get_obj(doc=d)
|
||||
psd_obj.get_item_details(self.doc.delivery_note)
|
||||
|
||||
|
||||
def get_recommended_case_no(self):
|
||||
"""
|
||||
Returns the next case no. for a new packing slip for a delivery
|
||||
note
|
||||
"""
|
||||
recommended_case_no = webnotes.conn.sql("""\
|
||||
SELECT MAX(to_case_no) FROM `tabPacking Slip`
|
||||
WHERE delivery_note = %(delivery_note)s AND docstatus=1""", self.doc.fields)
|
||||
|
||||
return cint(recommended_case_no[0][0]) + 1
|
||||
|
||||
|
||||
345
stock/doctype/packing_slip/packing_slip.txt
Normal file
345
stock/doctype/packing_slip/packing_slip.txt
Normal file
@@ -0,0 +1,345 @@
|
||||
# DocType, Packing Slip
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-15 12:15:08',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-06-29 12:24:16',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1328091392',
|
||||
'autoname': u'PS.#######',
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Generate packing slips for packages to be delivered. Used to notify package number, package contents and its weight.',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Transaction',
|
||||
'is_submittable': 1,
|
||||
'is_transaction_doc': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'read_only_onload': 1,
|
||||
'search_fields': u'delivery_note',
|
||||
'section_style': u'Simple',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'[%(delivery_note)s] Case Nos: %(from_case_no)s - %(to_case_no)s | Net Weight: %(net_weight_pkg)s %(net_weight_uom)s | Gross Weight: %(gross_weight_pkg)s %(gross_weight_uom)s',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Packing Slip',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Packing Slip',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Packing Slip
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Packing Slip'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# 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'Material Master Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material Manager',
|
||||
'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'All'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'packing_slip_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Packing Slip Items',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Indicates that the package is a part of this delivery',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_note',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Delivery Note',
|
||||
'options': u'Delivery Note',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Series',
|
||||
'no_copy': 0,
|
||||
'options': u'PS',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'section_break0',
|
||||
'fieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Identification of the package for the delivery (for print)',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'from_case_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'From Package No.',
|
||||
'no_copy': 1,
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'If more than one package of the same type (for print)',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'to_case_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'To Package No.',
|
||||
'no_copy': 1,
|
||||
'permlevel': 0,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'package_item_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Package Item Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_details',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Items',
|
||||
'options': u'Packing Slip Item',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'package_weight_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Package Weight Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The net weight of this package. (calculated automatically as sum of net weight of items)',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'net_weight_pkg',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Net Weight',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'net_weight_uom',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Net Weight UOM',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break4',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The gross weight of the package. Usually net weight + packaging material weight. (for print)',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'gross_weight_pkg',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Gross Weight',
|
||||
'no_copy': 1,
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'gross_weight_uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Gross Weight UOM',
|
||||
'no_copy': 1,
|
||||
'options': u'UOM',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'misc_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Misc Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amended_from',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Amended From',
|
||||
'no_copy': 1,
|
||||
'options': u'Packing Slip',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': u'eval:doc.amended_from',
|
||||
'description': u'The date at which current entry is corrected in the system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amendment_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Amendment Date',
|
||||
'no_copy': 1,
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
}
|
||||
]
|
||||
1
stock/doctype/packing_slip_item/__init__.py
Normal file
1
stock/doctype/packing_slip_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
46
stock/doctype/packing_slip_item/packing_slip_item.py
Normal file
46
stock/doctype/packing_slip_item/packing_slip_item.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# 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
|
||||
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
def get_item_details(self, delivery_note):
|
||||
res = webnotes.conn.sql("""\
|
||||
SELECT item_name, SUM(IFNULL(qty, 0)) as total_qty,
|
||||
IFNULL(packed_qty, 0) as packed_qty, stock_uom
|
||||
FROM `tabDelivery Note Item`
|
||||
WHERE parent=%s AND item_code=%s GROUP BY item_code""",
|
||||
(delivery_note, self.doc.item_code), as_dict=1)
|
||||
|
||||
if res and len(res)>0:
|
||||
res = res[0]
|
||||
res['qty'] = res['total_qty'] - res['packed_qty']
|
||||
res['qty'] = self.doc.qty or (res['qty']>=0 and res['qty'] or 0)
|
||||
del res['total_qty']
|
||||
del res['packed_qty']
|
||||
self.doc.fields.update(res)
|
||||
|
||||
res = webnotes.conn.sql("""\
|
||||
SELECT net_weight, weight_uom FROM `tabItem`
|
||||
WHERE name=%s""", self.doc.item_code, as_dict=1)
|
||||
|
||||
if res and len(res)>0:
|
||||
res = res[0]
|
||||
self.doc.fields.update(res)
|
||||
113
stock/doctype/packing_slip_item/packing_slip_item.txt
Normal file
113
stock/doctype/packing_slip_item/packing_slip_item.txt
Normal file
@@ -0,0 +1,113 @@
|
||||
# DocType, Packing Slip Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:34',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:34',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'PSD/.#######',
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'show_in_menu': 0,
|
||||
'version': 9
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Packing Slip Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Packing Slip Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Packing Slip Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item Code',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Item Name',
|
||||
'permlevel': 1,
|
||||
'width': u'200px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Quantity',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'UOM',
|
||||
'permlevel': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'net_weight',
|
||||
'fieldtype': u'Float',
|
||||
'label': u'Net Weight',
|
||||
'permlevel': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'weight_uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Weight UOM',
|
||||
'options': u'UOM',
|
||||
'permlevel': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'page_break',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Page Break',
|
||||
'permlevel': 0
|
||||
}
|
||||
]
|
||||
1
stock/doctype/purchase_receipt/__init__.py
Normal file
1
stock/doctype/purchase_receipt/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
317
stock/doctype/purchase_receipt/purchase_receipt.js
Normal file
317
stock/doctype/purchase_receipt/purchase_receipt.js
Normal file
@@ -0,0 +1,317 @@
|
||||
// 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 = "Purchase Receipt Item";
|
||||
cur_frm.cscript.fname = "purchase_receipt_details";
|
||||
cur_frm.cscript.other_fname = "purchase_tax_details";
|
||||
|
||||
wn.require('erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
||||
wn.require('erpnext/buying/doctype/purchase_common/purchase_common.js');
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/setup/doctype/notification_control/notification_control.js');
|
||||
|
||||
//========================== On Load ================================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(!doc.fiscal_year && doc.__islocal){ set_default_values(doc);}
|
||||
if (!doc.posting_date) doc.posting_date = dateutil.obj_to_str(new Date());
|
||||
if (!doc.transaction_date) doc.transaction_date = dateutil.obj_to_str(new Date());
|
||||
if (!doc.status) doc.status = 'Draft';
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
|
||||
var callback = function(doc, dt, dn) {
|
||||
var callback1 = function(doc, dt, dn) {
|
||||
if(doc.__islocal){
|
||||
cur_frm.cscript.get_default_schedule_date(doc);
|
||||
}
|
||||
}
|
||||
// defined in purchase_common.js
|
||||
cur_frm.cscript.update_item_details(doc, dt, dn, callback1);
|
||||
}
|
||||
cur_frm.cscript.dynamic_label(doc, dt, dn, callback);
|
||||
}
|
||||
|
||||
//========================== Refresh ===============================================================
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
cur_frm.clear_custom_buttons();
|
||||
|
||||
erpnext.hide_naming_series();
|
||||
if(doc.supplier) $(cur_frm.fields_dict.contact_section.row.wrapper).toggle(true);
|
||||
else $(cur_frm.fields_dict.contact_section.row.wrapper).toggle(false);
|
||||
|
||||
if (!cur_frm.cscript.is_onload) cur_frm.cscript.dynamic_label(doc, cdt, cdn);
|
||||
|
||||
if(doc.docstatus == 1){
|
||||
if (doc.per_billed < 100) cur_frm.add_custom_button('Make Purchase Invoice', cur_frm.cscript['Make Purchase Invoice']);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript['Send SMS']);
|
||||
}
|
||||
|
||||
if(wn.boot.control_panel.country == 'India') {
|
||||
unhide_field(['challan_no', 'challan_date']);
|
||||
}
|
||||
}
|
||||
|
||||
//Supplier
|
||||
cur_frm.cscript.supplier = function(doc,dt,dn) {
|
||||
if (doc.supplier) {
|
||||
get_server_fields('get_default_supplier_address',
|
||||
JSON.stringify({ supplier: doc.supplier }),'', doc, dt, dn, 1, function() {
|
||||
cur_frm.refresh();
|
||||
});
|
||||
$(cur_frm.fields_dict.contact_section.row.wrapper).toggle(true);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.supplier_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.supplier) get_server_fields('get_supplier_address', JSON.stringify({supplier: doc.supplier, address: doc.supplier_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE supplier = "'+ doc.supplier +'" 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 supplier = "'+ doc.supplier +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict.supplier_address.on_new = function(dn) {
|
||||
locals['Address'][dn].supplier = locals[cur_frm.doctype][cur_frm.docname].supplier;
|
||||
locals['Address'][dn].supplier_name = locals[cur_frm.doctype][cur_frm.docname].supplier_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].supplier = locals[cur_frm.doctype][cur_frm.docname].supplier;
|
||||
locals['Contact'][dn].supplier_name = locals[cur_frm.doctype][cur_frm.docname].supplier_name;
|
||||
}
|
||||
|
||||
|
||||
// Get Purchase Order Button
|
||||
// -----------------
|
||||
cur_frm.cscript.pull_purchase_order_details = function(doc, dt, dn) {
|
||||
var callback = function(r,rt) {
|
||||
//unhide_field(['supplier_address','contact_person','supplier_name','address_display', 'contact_display', 'contact_mobile','contact_email']);
|
||||
refresh_many(['supplier','supplier_address','contact_person', 'supplier_name', 'address_display', 'contact_display','contact_mobile', 'contact_email', 'purchase_receipt_details', 'purchase_tax_details']);
|
||||
}
|
||||
$c_obj(make_doclist(dt,dn),'get_po_details','',callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================ create new contact ============================================================================
|
||||
cur_frm.cscript.new_contact = function(){
|
||||
tn = createLocal('Contact');
|
||||
locals['Contact'][tn].is_supplier = 1;
|
||||
if(doc.supplier) locals['Contact'][tn].supplier = doc.supplier;
|
||||
loaddoc('Contact', tn);
|
||||
}
|
||||
|
||||
//======================= posting date =============================
|
||||
cur_frm.cscript.transaction_date = function(doc,cdt,cdn){
|
||||
if(doc.__islocal){
|
||||
cur_frm.cscript.get_default_schedule_date(doc);
|
||||
}
|
||||
}
|
||||
|
||||
// ***************** Get project name *****************
|
||||
cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('project_name').get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.status = "Open" AND `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
//========================= Overloaded query for link batch_no =============================================================
|
||||
cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('batch_no').get_query= function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.item_code){
|
||||
return "SELECT tabBatch.name, tabBatch.description FROM tabBatch WHERE tabBatch.docstatus != 2 AND tabBatch.item = '"+ d.item_code +"' AND `tabBatch`.`name` like '%s' ORDER BY `tabBatch`.`name` DESC LIMIT 50"
|
||||
}
|
||||
else{
|
||||
alert("Please enter Item Code.");
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){
|
||||
if(doc.select_print_heading){
|
||||
// print heading
|
||||
cur_frm.pformat.print_heading = doc.select_print_heading;
|
||||
}
|
||||
else
|
||||
cur_frm.pformat.print_heading = "Purchase Receipt";
|
||||
}
|
||||
// ***************** Get Print Heading *****************
|
||||
cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT `tabPrint Heading`.name FROM `tabPrint Heading` WHERE `tabPrint Heading`.docstatus !=2 AND `tabPrint Heading`.name LIKE "%s" ORDER BY `tabPrint Heading`.name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
//========================= Received Qty =============================================================
|
||||
|
||||
cur_frm.cscript.received_qty = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
ret = {
|
||||
'qty' : 0,
|
||||
'stock_qty': 0,
|
||||
'rejected_qty' : 0
|
||||
}
|
||||
set_multiple('Purchase Receipt Item', cdn, ret, 'purchase_receipt_details');
|
||||
cur_frm.cscript.calc_amount(doc, 2);
|
||||
}
|
||||
|
||||
//======================== Qty (Accepted Qty) =========================================================
|
||||
|
||||
cur_frm.cscript.qty = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
// Step 1 :=> Check If Qty > Received Qty
|
||||
if (flt(d.qty) > flt(d.received_qty)) {
|
||||
alert("Accepted Qty cannot be greater than Received Qty")
|
||||
ret = {
|
||||
'qty' : 0,
|
||||
'stock_qty': 0,
|
||||
'rejected_qty' : 0
|
||||
}
|
||||
// => Set Qty = 0 and rejected_qty = 0
|
||||
set_multiple('Purchase Receipt Item', cdn, ret, 'purchase_receipt_details');
|
||||
cur_frm.cscript.calc_amount(doc, 2);
|
||||
// => Return
|
||||
return
|
||||
}
|
||||
// Step 2 :=> Check IF Qty <= REceived Qty
|
||||
else {
|
||||
ret = {
|
||||
'rejected_qty':flt(d.received_qty) - flt(d.qty)
|
||||
}
|
||||
// => Set Rejected Qty = Received Qty - Qty
|
||||
set_multiple('Purchase Receipt Item', cdn, ret, 'purchase_receipt_details');
|
||||
// => Calculate Amount
|
||||
cur_frm.cscript.calc_amount(doc, 2);
|
||||
cur_frm.cscript.update_stock_qty(doc,cdt,cdn);
|
||||
}
|
||||
}
|
||||
|
||||
//======================== Rejected Qty =========================================================
|
||||
cur_frm.cscript.rejected_qty = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
// Step 1 :=> Check If Rejected Qty > Received Qty
|
||||
if (flt(d.rejected_qty) > flt(d.received_qty)) {
|
||||
alert("Rejected Qty cannot be greater than Received Qty")
|
||||
ret = {
|
||||
'qty' : 0,
|
||||
'stock_qty': 0,
|
||||
'rejected_qty' : 0
|
||||
}
|
||||
// => Set Qty = 0 and rejected_qty = 0
|
||||
set_multiple('Purchase Receipt Item', cdn, ret, 'purchase_receipt_details');
|
||||
cur_frm.cscript.calc_amount(doc, 2);
|
||||
// => Return
|
||||
return
|
||||
}
|
||||
// Step 2 :=> Check IF Rejected Qty <= REceived Qty
|
||||
else {
|
||||
ret = {
|
||||
'qty':flt(d.received_qty) - flt(d.rejected_qty)
|
||||
}
|
||||
// => Set Qty = Received Qty - Rejected Qty
|
||||
set_multiple('Purchase Receipt Item', cdn, ret, 'purchase_receipt_details');
|
||||
// Calculate Amount
|
||||
cur_frm.cscript.calc_amount(doc, 2);
|
||||
cur_frm.cscript.update_stock_qty(doc,cdt,cdn);
|
||||
}
|
||||
}
|
||||
|
||||
//================================= Purchase Order No Get Query ====================================
|
||||
cur_frm.fields_dict['purchase_order_no'].get_query = function(doc) {
|
||||
if (doc.supplier)
|
||||
return 'SELECT DISTINCT `tabPurchase Order`.`name` FROM `tabPurchase Order` WHERE `tabPurchase Order`.`supplier` = "' +doc.supplier + '" and`tabPurchase Order`.`docstatus` = 1 and `tabPurchase Order`.`status` != "Stopped" and ifnull(`tabPurchase Order`.`per_received`, 0) < 100 and `tabPurchase Order`.`currency` = ifnull("' +doc.currency+ '","") and `tabPurchase Order`.company = "'+ doc.company +'" and `tabPurchase Order`.%(key)s LIKE "%s" ORDER BY `tabPurchase Order`.`name` DESC LIMIT 50';
|
||||
else
|
||||
return 'SELECT DISTINCT `tabPurchase Order`.`name` FROM `tabPurchase Order` WHERE `tabPurchase Order`.`docstatus` = 1 and `tabPurchase Order`.`company` = "'+ doc.company +'" and `tabPurchase Order`.`status` != "Stopped" and ifnull(`tabPurchase Order`.`per_received`, 0) < 100 and `tabPurchase Order`.%(key)s LIKE "%s" ORDER BY `tabPurchase Order`.`name` DESC LIMIT 50';
|
||||
}
|
||||
|
||||
// QA INspection report get_query
|
||||
//---------------------------------
|
||||
|
||||
cur_frm.fields_dict.purchase_receipt_details.grid.get_field("qa_no").get_query = function(doc) {
|
||||
return 'SELECT `tabQuality Inspection`.name FROM `tabQuality Inspection` WHERE `tabQuality Inspection`.docstatus = 1 AND `tabQuality Inspection`.%(key)s LIKE "%s"';
|
||||
}
|
||||
|
||||
// On Button Click Functions
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// ================================ Make Purchase Invoice ==========================================
|
||||
cur_frm.cscript['Make Purchase Invoice'] = function() {
|
||||
n = createLocal('Purchase Invoice');
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals['Purchase Invoice'][n]]),
|
||||
'from_doctype': cur_frm.doc.doctype,
|
||||
'to_doctype':'Purchase Invoice',
|
||||
'from_docname': cur_frm.doc.name,
|
||||
'from_to_list':"[['Purchase Receipt','Purchase Invoice'],['Purchase Receipt Item','Purchase Invoice Item'],['Purchase Taxes and Charges','Purchase Taxes and Charges']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc('Purchase Invoice', n);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//****************** For print sales order no and date*************************
|
||||
cur_frm.pformat.purchase_order_no = function(doc, cdt, cdn){
|
||||
//function to make row of table
|
||||
|
||||
var make_row = function(title,val1, val2, bold){
|
||||
var bstart = '<b>'; var bend = '</b>';
|
||||
|
||||
return '<tr><td style="width:39%;">'+(bold?bstart:'')+title+(bold?bend:'')+'</td>'
|
||||
+'<td style="width:61%;text-align:left;">'+val1+(val2?' ('+dateutil.str_to_user(val2)+')':'')+'</td>'
|
||||
+'</tr>'
|
||||
}
|
||||
|
||||
out ='';
|
||||
|
||||
var cl = getchildren('Purchase Receipt Item',doc.name,'purchase_receipt_details');
|
||||
|
||||
// outer table
|
||||
var out='<div><table class="noborder" style="width:100%"><tr><td style="width: 50%"></td><td>';
|
||||
|
||||
// main table
|
||||
out +='<table class="noborder" style="width:100%">';
|
||||
|
||||
// add rows
|
||||
if(cl.length){
|
||||
prevdoc_list = new Array();
|
||||
for(var i=0;i<cl.length;i++){
|
||||
if(cl[i].prevdoc_doctype == 'Purchase Order' && cl[i].prevdoc_docname && prevdoc_list.indexOf(cl[i].prevdoc_docname) == -1) {
|
||||
prevdoc_list.push(cl[i].prevdoc_docname);
|
||||
if(prevdoc_list.length ==1)
|
||||
out += make_row(cl[i].prevdoc_doctype, cl[i].prevdoc_docname, cl[i].prevdoc_date,0);
|
||||
else
|
||||
out += make_row('', cl[i].prevdoc_docname, cl[i].prevdoc_date,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out +='</table></td></tr></table></div>';
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
||||
var args = {
|
||||
type: 'Purchase Receipt',
|
||||
doctype: 'Purchase Receipt'
|
||||
}
|
||||
cur_frm.cscript.notify(doc, args);
|
||||
}
|
||||
479
stock/doctype/purchase_receipt/purchase_receipt.py
Normal file
479
stock/doctype/purchase_receipt/purchase_receipt.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=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.defaults = get_defaults()
|
||||
self.tname = 'Purchase Receipt Item'
|
||||
self.fname = 'purchase_receipt_details'
|
||||
self.count = 0
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# Client Trigger Functions
|
||||
#----------------------------------------------------------------------------------------------------
|
||||
|
||||
def get_default_schedule_date(self):
|
||||
get_obj(dt = 'Purchase Common').get_default_schedule_date(self)
|
||||
|
||||
#-----------------Validation For Fiscal Year------------------------
|
||||
def validate_fiscal_year(self):
|
||||
get_obj(dt = 'Purchase Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Transaction Date')
|
||||
|
||||
|
||||
# Get Item Details
|
||||
def get_item_details(self, arg = ''):
|
||||
if arg:
|
||||
return get_obj(dt='Purchase Common').get_item_details(self,arg)
|
||||
else:
|
||||
import json
|
||||
obj = get_obj('Purchase Common')
|
||||
for doc in self.doclist:
|
||||
if doc.fields.get('item_code'):
|
||||
temp = {
|
||||
'item_code': doc.fields.get('item_code'),
|
||||
'warehouse': doc.fields.get('warehouse')
|
||||
}
|
||||
ret = obj.get_item_details(self, json.dumps(temp))
|
||||
for r in ret:
|
||||
if not doc.fields.get(r):
|
||||
doc.fields[r] = ret[r]
|
||||
|
||||
|
||||
# Get UOM Details
|
||||
def get_uom_details(self, arg = ''):
|
||||
return get_obj(dt='Purchase Common').get_uom_details(arg)
|
||||
|
||||
# GET TERMS & CONDITIONS
|
||||
# =====================================================================================
|
||||
def get_tc_details(self):
|
||||
return get_obj('Purchase Common').get_tc_details(self)
|
||||
|
||||
|
||||
# get available qty at warehouse
|
||||
def get_bin_details(self, arg = ''):
|
||||
return get_obj(dt='Purchase Common').get_bin_details(arg)
|
||||
|
||||
# Pull Purchase Order
|
||||
def get_po_details(self):
|
||||
self.validate_prev_docname()
|
||||
get_obj('DocType Mapper', 'Purchase Order-Purchase Receipt').dt_map('Purchase Order', 'Purchase Receipt', self.doc.purchase_order_no, self.doc, self.doclist, "[['Purchase Order','Purchase Receipt'],['Purchase Order Item', 'Purchase Receipt Item'],['Purchase Taxes and Charges','Purchase Taxes and Charges']]")
|
||||
|
||||
# validate if PO has been pulled twice
|
||||
def validate_prev_docname(self):
|
||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
||||
if self.doc.purchase_order_no and d.prevdoc_docname and self.doc.purchase_order_no == d.prevdoc_docname:
|
||||
msgprint(cstr(self.doc.purchase_order_no) + " Purchase Order details have already been pulled. ")
|
||||
raise Exception
|
||||
|
||||
|
||||
# validation
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
# validate accepted and rejected qty
|
||||
def validate_accepted_rejected_qty(self):
|
||||
for d in getlist(self.doclist, "purchase_receipt_details"):
|
||||
|
||||
# If Reject Qty than Rejected warehouse is mandatory
|
||||
if flt(d.rejected_qty) and (not self.doc.rejected_warehouse):
|
||||
msgprint("Rejected Warehouse is necessary if there are rejections.")
|
||||
raise Exception
|
||||
|
||||
# Check Received Qty = Accepted Qty + Rejected Qty
|
||||
if ((flt(d.qty) + flt(d.rejected_qty)) != flt(d.received_qty)):
|
||||
|
||||
msgprint("Sum of Accepted Qty and Rejected Qty must be equal to Received quantity. Error for Item: " + cstr(d.item_code))
|
||||
raise Exception
|
||||
|
||||
|
||||
def validate_challan_no(self):
|
||||
"Validate if same challan no exists for same supplier in a submitted purchase receipt"
|
||||
if self.doc.challan_no:
|
||||
exists = webnotes.conn.sql("""
|
||||
SELECT name FROM `tabPurchase Receipt`
|
||||
WHERE name!=%s AND supplier=%s AND challan_no=%s
|
||||
AND docstatus=1""", (self.doc.name, self.doc.supplier, self.doc.challan_no))
|
||||
if exists:
|
||||
webnotes.msgprint("Another Purchase Receipt using the same Challan No. already exists.\
|
||||
Please enter a valid Challan No.", raise_exception=1)
|
||||
|
||||
|
||||
# update valuation rate
|
||||
def update_valuation_rate(self):
|
||||
total_b_cost = flt(self.doc.buying_cost_transport) + flt(self.doc.buying_cost_taxes) + flt(self.doc.buying_cost_other)
|
||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
||||
if flt(self.doc.net_total) and flt(d.qty):
|
||||
#d.valuation_rate = (flt(d.purchase_rate) + ((flt(d.amount) * (total_b_cost)) / (self.doc.net_total * flt(d.qty))) + (flt(d.rm_supp_cost) / flt(d.qty))) / flt(d.conversion_factor)
|
||||
d.valuation_rate = (flt(d.purchase_rate) + ((flt(d.amount) * (total_b_cost)) / (self.doc.net_total * flt(d.qty))) + (flt(d.rm_supp_cost) / flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
|
||||
|
||||
# Check for Stopped status
|
||||
def check_for_stopped_status(self, pc_obj):
|
||||
check_list =[]
|
||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
||||
if d.fields.has_key('prevdoc_docname') and d.prevdoc_docname and d.prevdoc_docname not in check_list:
|
||||
check_list.append(d.prevdoc_docname)
|
||||
pc_obj.check_for_stopped_status( d.prevdoc_doctype, d.prevdoc_docname)
|
||||
|
||||
#check in manage account if purchase order required or not.
|
||||
# ====================================================================================
|
||||
def po_required(self):
|
||||
res = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'po_required'")
|
||||
if res and res[0][0]== 'Yes':
|
||||
for d in getlist(self.doclist,'purchase_receipt_details'):
|
||||
if not d.prevdoc_docname:
|
||||
msgprint("Purchse Order No. required against item %s"%d.item_code)
|
||||
raise Exception
|
||||
|
||||
|
||||
# validate
|
||||
def validate(self):
|
||||
self.po_required()
|
||||
self.validate_fiscal_year()
|
||||
set(self.doc, 'status', 'Draft') # set status as "Draft"
|
||||
self.validate_accepted_rejected_qty()
|
||||
self.validate_inspection() # Validate Inspection
|
||||
get_obj('Stock Ledger').validate_serial_no(self, 'purchase_receipt_details')
|
||||
self.validate_challan_no()
|
||||
|
||||
pc_obj = get_obj(dt='Purchase Common')
|
||||
pc_obj.validate_for_items(self)
|
||||
pc_obj.validate_mandatory(self)
|
||||
pc_obj.validate_conversion_rate(self)
|
||||
pc_obj.get_prevdoc_date(self)
|
||||
pc_obj.validate_reference_value(self)
|
||||
self.check_for_stopped_status(pc_obj)
|
||||
|
||||
# get total in words
|
||||
dcc = TransactionBase().get_company_currency(self.doc.company)
|
||||
self.doc.in_words = pc_obj.get_total_in_words(dcc, self.doc.grand_total)
|
||||
self.doc.in_words_import = pc_obj.get_total_in_words(self.doc.currency, self.doc.grand_total_import)
|
||||
# update valuation rate
|
||||
self.update_valuation_rate()
|
||||
|
||||
|
||||
# On Update
|
||||
# ----------------------------------------------------------------------------------------------------
|
||||
def on_update(self):
|
||||
if self.doc.rejected_warehouse:
|
||||
for d in getlist(self.doclist,'purchase_receipt_details'):
|
||||
d.rejected_warehouse = self.doc.rejected_warehouse
|
||||
|
||||
self.update_rw_material_detail()
|
||||
get_obj('Stock Ledger').scrub_serial_nos(self)
|
||||
self.scrub_rejected_serial_nos()
|
||||
|
||||
|
||||
def scrub_rejected_serial_nos(self):
|
||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
||||
if d.rejected_serial_no:
|
||||
d.rejected_serial_no = d.rejected_serial_no.replace(',', '\n')
|
||||
d.save()
|
||||
|
||||
|
||||
|
||||
# On Submit
|
||||
# -----------------------------------------------------------------------------------------------------
|
||||
|
||||
# Update Stock
|
||||
def update_stock(self, is_submit):
|
||||
pc_obj = get_obj('Purchase Common')
|
||||
self.values = []
|
||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
||||
# Check if is_stock_item == 'Yes'
|
||||
if sql("select is_stock_item from tabItem where name=%s", d.item_code)[0][0]=='Yes':
|
||||
ord_qty = 0
|
||||
pr_qty = flt(d.qty) * flt(d.conversion_factor)
|
||||
|
||||
# Check If Prevdoc Doctype is Purchase Order
|
||||
if cstr(d.prevdoc_doctype) == 'Purchase Order':
|
||||
# get qty and pending_qty of prevdoc
|
||||
curr_ref_qty = pc_obj.get_qty( d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, 'Purchase Order Item', 'Purchase Order - Purchase Receipt', self.doc.name)
|
||||
max_qty, qty, curr_qty = flt(curr_ref_qty.split('~~~')[1]), flt(curr_ref_qty.split('~~~')[0]), 0
|
||||
|
||||
if flt(qty) + flt(pr_qty) > flt(max_qty):
|
||||
curr_qty = (flt(max_qty) - flt(qty)) * flt(d.conversion_factor)
|
||||
else:
|
||||
curr_qty = flt(pr_qty)
|
||||
|
||||
ord_qty = -flt(curr_qty)
|
||||
# update order qty in bin
|
||||
bin = get_obj('Warehouse', d.warehouse).update_bin(0, 0, (is_submit and 1 or -1) * flt(ord_qty), 0, 0, d.item_code, self.doc.posting_date)
|
||||
|
||||
# UPDATE actual qty to warehouse by pr_qty
|
||||
self.make_sl_entry(d, d.warehouse, flt(pr_qty), d.valuation_rate, is_submit)
|
||||
# UPDATE actual to rejected warehouse by rejected qty
|
||||
if flt(d.rejected_qty) > 0:
|
||||
self.make_sl_entry(d, self.doc.rejected_warehouse, flt(d.rejected_qty) * flt(d.conversion_factor), d.valuation_rate, is_submit, rejected = 1)
|
||||
|
||||
self.bk_flush_supp_wh(is_submit)
|
||||
|
||||
if self.values:
|
||||
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
|
||||
|
||||
|
||||
# make Stock Entry
|
||||
def make_sl_entry(self, d, wh, qty, in_value, is_submit, rejected = 0):
|
||||
if rejected:
|
||||
serial_no = d.rejected_serial_no
|
||||
else:
|
||||
serial_no = d.serial_no
|
||||
|
||||
self.values.append({
|
||||
'item_code' : d.fields.has_key('item_code') and d.item_code or d.rm_item_code,
|
||||
'warehouse' : wh,
|
||||
'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'),
|
||||
'posting_date' : self.doc.posting_date,
|
||||
'posting_time' : self.doc.posting_time,
|
||||
'voucher_type' : 'Purchase Receipt',
|
||||
'voucher_no' : self.doc.name,
|
||||
'voucher_detail_no' : d.name,
|
||||
'actual_qty' : qty,
|
||||
'stock_uom' : d.stock_uom,
|
||||
'incoming_rate' : in_value,
|
||||
'company' : self.doc.company,
|
||||
'fiscal_year' : self.doc.fiscal_year,
|
||||
'is_cancelled' : (is_submit==1) and 'No' or 'Yes',
|
||||
'batch_no' : d.batch_no,
|
||||
'serial_no' : serial_no
|
||||
})
|
||||
|
||||
|
||||
def validate_inspection(self):
|
||||
for d in getlist(self.doclist, 'purchase_receipt_details'): #Enter inspection date for all items that require inspection
|
||||
ins_reqd = sql("select inspection_required from `tabItem` where name = %s", (d.item_code), as_dict = 1)
|
||||
ins_reqd = ins_reqd and ins_reqd[0]['inspection_required'] or 'No'
|
||||
if ins_reqd == 'Yes' and not d.qa_no:
|
||||
msgprint("Item: " + d.item_code + " requires QA Inspection. Please enter QA No or report to authorized person to create Quality Inspection")
|
||||
|
||||
# Check for Stopped status
|
||||
def check_for_stopped_status(self, pc_obj):
|
||||
check_list =[]
|
||||
for d in getlist(self.doclist, 'purchase_receipt_details'):
|
||||
if d.fields.has_key('prevdoc_docname') and d.prevdoc_docname and d.prevdoc_docname not in check_list:
|
||||
check_list.append(d.prevdoc_docname)
|
||||
pc_obj.check_for_stopped_status( d.prevdoc_doctype, d.prevdoc_docname)
|
||||
|
||||
|
||||
# on submit
|
||||
def on_submit(self):
|
||||
# Check for Approving Authority
|
||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total)
|
||||
|
||||
# Set status as Submitted
|
||||
set(self.doc,'status', 'Submitted')
|
||||
pc_obj = get_obj('Purchase Common')
|
||||
|
||||
# Update Previous Doc i.e. update pending_qty and Status accordingly
|
||||
pc_obj.update_prevdoc_detail(self, is_submit = 1)
|
||||
|
||||
# Update Serial Record
|
||||
get_obj('Stock Ledger').update_serial_record(self, 'purchase_receipt_details', is_submit = 1, is_incoming = 1)
|
||||
|
||||
# Update Stock
|
||||
self.update_stock(is_submit = 1)
|
||||
|
||||
# Update last purchase rate
|
||||
pc_obj.update_last_purchase_rate(self, 1)
|
||||
|
||||
|
||||
|
||||
#On Cancel
|
||||
#----------------------------------------------------------------------------------------------------
|
||||
def check_next_docstatus(self):
|
||||
submit_rv = sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||
if submit_rv:
|
||||
msgprint("Purchase Invoice : " + cstr(self.submit_rv[0][0]) + " has already been submitted !")
|
||||
raise Exception , "Validation Error."
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
pc_obj = get_obj('Purchase Common')
|
||||
|
||||
self.check_for_stopped_status(pc_obj)
|
||||
# 1.Check if Purchase Invoice has been submitted against current Purchase Order
|
||||
# pc_obj.check_docstatus(check = 'Next', doctype = 'Purchase Invoice', docname = self.doc.name, detail_doctype = 'Purchase Invoice Item')
|
||||
|
||||
submitted = sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = '%s' and t1.docstatus = 1" % self.doc.name)
|
||||
if submitted:
|
||||
msgprint("Purchase Invoice : " + cstr(submitted[0][0]) + " has already been submitted !")
|
||||
raise Exception
|
||||
|
||||
# 2.Set Status as Cancelled
|
||||
set(self.doc,'status','Cancelled')
|
||||
|
||||
# 3. Cancel Serial No
|
||||
get_obj('Stock Ledger').update_serial_record(self, 'purchase_receipt_details', is_submit = 0, is_incoming = 1)
|
||||
|
||||
# 4.Update Bin
|
||||
self.update_stock(is_submit = 0)
|
||||
|
||||
# 5.Update Purchase Requests Pending Qty and accordingly it's Status
|
||||
pc_obj.update_prevdoc_detail(self, is_submit = 0)
|
||||
|
||||
# 6. Update last purchase rate
|
||||
pc_obj.update_last_purchase_rate(self, 0)
|
||||
|
||||
|
||||
#----------- code for Sub-contracted Items -------------------
|
||||
#--------check for sub-contracted items and accordingly update PR raw material detail table--------
|
||||
def update_rw_material_detail(self):
|
||||
|
||||
for d in getlist(self.doclist,'purchase_receipt_details'):
|
||||
item_det = sql("select is_sub_contracted_item, is_purchase_item from `tabItem` where name = '%s'"%(d.item_code))
|
||||
|
||||
if item_det[0][0] == 'Yes':
|
||||
if item_det[0][1] == 'Yes':
|
||||
if not self.doc.is_subcontracted:
|
||||
msgprint("Please enter whether purchase receipt to be made for subcontracting or for purchase in 'Is Subcontracted' field .")
|
||||
raise Exception
|
||||
if self.doc.is_subcontracted == 'Yes':
|
||||
if not self.doc.supplier_warehouse:
|
||||
msgprint("Please Enter Supplier Warehouse for subcontracted Items")
|
||||
raise Exception
|
||||
self.add_bom(d)
|
||||
else:
|
||||
self.doclist = self.doc.clear_table(self.doclist,'pr_raw_material_details',1)
|
||||
self.doc.save()
|
||||
elif item_det[0][1] == 'No':
|
||||
if not self.doc.supplier_warehouse:
|
||||
msgprint("Please Enter Supplier Warehouse for subcontracted Items")
|
||||
raise Exception
|
||||
self.add_bom(d)
|
||||
|
||||
self.delete_irrelevant_raw_material()
|
||||
#---------------calculate amt in Purchase Receipt Item Supplied-------------
|
||||
self.calculate_amount(d)
|
||||
|
||||
|
||||
def add_bom(self, d):
|
||||
#----- fetching default bom from Bill of Materials instead of Item Master --
|
||||
bom_det = sql("select t1.item, t2.item_code, t2.qty_consumed_per_unit, t2.moving_avg_rate, t2.value_as_per_mar, t2.stock_uom, t2.name, t2.description from `tabBOM` t1, `tabBOM Item` t2 where t2.parent = t1.name and t1.item = '%s' and ifnull(t1.is_default,0) = 1 and t1.docstatus = 1 and t2.docstatus =1" % d.item_code)
|
||||
if not bom_det:
|
||||
msgprint("No default BOM exists for item: %s" % d.item_code)
|
||||
raise Exception
|
||||
else:
|
||||
#-------------- add child function--------------------
|
||||
chgd_rqd_qty = []
|
||||
for i in bom_det:
|
||||
|
||||
if i and not sql("select name from `tabPurchase Receipt Item Supplied` where reference_name = '%s' and bom_detail_no = '%s' and parent = '%s' " %(d.name, i[6], self.doc.name)):
|
||||
|
||||
rm_child = addchild(self.doc, 'pr_raw_material_details', 'Purchase Receipt Item Supplied', 1, self.doclist)
|
||||
|
||||
rm_child.reference_name = d.name
|
||||
rm_child.bom_detail_no = i and i[6] or ''
|
||||
rm_child.main_item_code = i and i[0] or ''
|
||||
rm_child.rm_item_code = i and i[1] or ''
|
||||
rm_child.description = i and i[7] or ''
|
||||
rm_child.stock_uom = i and i[5] or ''
|
||||
rm_child.rate = i and flt(i[3]) or flt(i[4])
|
||||
rm_child.conversion_factor = d.conversion_factor
|
||||
rm_child.required_qty = flt(i and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
|
||||
rm_child.consumed_qty = flt(i and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
|
||||
rm_child.amount = flt(flt(rm_child.consumed_qty)*flt(rm_child.rate))
|
||||
rm_child.save()
|
||||
chgd_rqd_qty.append(cstr(i[1]))
|
||||
else:
|
||||
act_qty = flt(i and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
|
||||
for pr_rmd in getlist(self.doclist, 'pr_raw_material_details'):
|
||||
if i and i[6] == pr_rmd.bom_detail_no and (flt(act_qty) != flt(pr_rmd.required_qty) or i[1] != pr_rmd.rm_item_code or i[7] != pr_rmd.description):
|
||||
chgd_rqd_qty.append(cstr(i[1]))
|
||||
pr_rmd.main_item_code = i[0]
|
||||
pr_rmd.rm_item_code = i[1]
|
||||
pr_rmd.description = i[7]
|
||||
pr_rmd.stock_uom = i[5]
|
||||
pr_rmd.required_qty = flt(act_qty)
|
||||
pr_rmd.consumed_qty = flt(act_qty)
|
||||
pr_rmd.rate = i and flt(i[3]) or flt(i[4])
|
||||
pr_rmd.amount = flt(flt(pr_rmd.consumed_qty)*flt(pr_rmd.rate))
|
||||
pr_rmd.save()
|
||||
if chgd_rqd_qty:
|
||||
msgprint("Please check consumed quantity for Raw Material Item Code: '%s'in Raw materials Detail Table" % ((len(chgd_rqd_qty) > 1 and ','.join(chgd_rqd_qty[:-1]) +' and ' + cstr(chgd_rqd_qty[-1:][0]) ) or cstr(chgd_rqd_qty[0])))
|
||||
|
||||
|
||||
# Delete irrelevant raw material from PR Raw material details
|
||||
#--------------------------------------------------------------
|
||||
def delete_irrelevant_raw_material(self):
|
||||
for d in getlist(self.doclist,'pr_raw_material_details'):
|
||||
if not sql("select name from `tabPurchase Receipt Item` where name = '%s' and parent = '%s' and item_code = '%s'" % (d.reference_name, self.doc.name, d.main_item_code)):
|
||||
d.parent = 'old_par:'+self.doc.name
|
||||
d.save()
|
||||
|
||||
def calculate_amount(self, d):
|
||||
amt = 0
|
||||
for i in getlist(self.doclist,'pr_raw_material_details'):
|
||||
|
||||
if(i.reference_name == d.name):
|
||||
#if i.consumed_qty == 0:
|
||||
# msgprint("consumed qty cannot be 0. Please Enter consumed qty ")
|
||||
#raise Exception
|
||||
i.amount = flt(i.consumed_qty)* flt(i.rate)
|
||||
amt += i.amount
|
||||
d.rm_supp_cost = amt
|
||||
d.save()
|
||||
|
||||
|
||||
# --------------- Back Flush function called on submit and on cancel from update stock
|
||||
def bk_flush_supp_wh(self, is_submit):
|
||||
for d in getlist(self.doclist, 'pr_raw_material_details'):
|
||||
#--------- -ve quantity is passed as raw material qty has to be decreased when PR is submitted and it has to be increased when PR is cancelled
|
||||
consumed_qty = - flt(d.consumed_qty)
|
||||
self.make_sl_entry(d, self.doc.supplier_warehouse, flt(consumed_qty), 0, is_submit)
|
||||
|
||||
|
||||
# get current_stock
|
||||
# ----------------
|
||||
def get_current_stock(self):
|
||||
for d in getlist(self.doclist, 'pr_raw_material_details'):
|
||||
if self.doc.supplier_warehouse:
|
||||
bin = sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.rm_item_code, self.doc.supplier_warehouse), as_dict = 1)
|
||||
d.current_stock = bin and flt(bin[0]['actual_qty']) or 0
|
||||
|
||||
|
||||
def get_rate(self,arg):
|
||||
return get_obj('Purchase Common').get_rate(arg,self)
|
||||
|
||||
def load_default_taxes(self):
|
||||
self.doclist = get_obj('Purchase Common').load_default_taxes(self)
|
||||
|
||||
def get_purchase_tax_details(self):
|
||||
self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self)
|
||||
1187
stock/doctype/purchase_receipt/purchase_receipt.txt
Executable file
1187
stock/doctype/purchase_receipt/purchase_receipt.txt
Executable file
File diff suppressed because it is too large
Load Diff
36
stock/doctype/purchase_receipt/purchase_receipt_list.js
Normal file
36
stock/doctype/purchase_receipt/purchase_receipt_list.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// render
|
||||
wn.doclistviews['Purchase Receipt'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d);
|
||||
this.fields = this.fields.concat([
|
||||
"`tabPurchase Receipt`.supplier_name",
|
||||
"group_concat(`tabPurchase Receipt Item`.prevdoc_docname) as purchase_order_no",
|
||||
"`tabPurchase Receipt`.posting_date",
|
||||
]);
|
||||
this.group_by = "`tabPurchase Receipt`.name";
|
||||
},
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(data.purchase_order_no) {
|
||||
data.purchase_order_no = data.purchase_order_no.split(",");
|
||||
var po_list = [];
|
||||
$.each(data.purchase_order_no, function(i, v){
|
||||
if(po_list.indexOf(v)==-1) po_list.push(
|
||||
repl("<a href=\"#Form/Purchase Order/%(name)s\">%(name)s</a>",
|
||||
{name: v}));
|
||||
});
|
||||
data.purchase_order_no = po_list.join(", ");
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '3%', content:'docstatus'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '32%', content:'supplier_name+tags', css: {color:'#222'}},
|
||||
{width: '30%', content:'purchase_order_no'},
|
||||
{width: '12%', content:'posting_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Purhcase Receipt Date", type: "date"}
|
||||
]
|
||||
});
|
||||
1
stock/doctype/purchase_receipt_item/__init__.py
Normal file
1
stock/doctype/purchase_receipt_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
592
stock/doctype/purchase_receipt_item/purchase_receipt_item.txt
Executable file
592
stock/doctype/purchase_receipt_item/purchase_receipt_item.txt
Executable file
@@ -0,0 +1,592 @@
|
||||
# DocType, Purchase Receipt Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-04-13 11:56:36',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-06-07 18:07:12',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'GRND/.#######',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'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'Purchase Receipt Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Purchase Receipt Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Purchase Receipt 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'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 0,
|
||||
'label': u'Item Name',
|
||||
'oldfieldname': u'item_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'received_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Recd Quantity',
|
||||
'oldfieldname': u'received_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Accepted Quantity',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'rejected_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Rejected Quantity',
|
||||
'oldfieldname': u'rejected_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'import_ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Ref Rate ',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'discount_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Discount %',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'import_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'import_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'import_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount',
|
||||
'oldfieldname': u'import_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Ref Rate *',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate *(Default Curr.)',
|
||||
'oldfieldname': u'purchase_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount (Default Curr.)',
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'label': u'Accepted Warehouse',
|
||||
'oldfieldname': u'warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'uom',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'UOM',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'conversion_factor',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Conversion Factor',
|
||||
'oldfieldname': u'conversion_factor',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Stock UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Text',
|
||||
'in_filter': 1,
|
||||
'label': u'Serial No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'serial_no',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'rejected_serial_no',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Rejected Serial No',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'batch_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Batch No',
|
||||
'oldfieldname': u'batch_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Batch',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'rejected_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Rejected Warehouse',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'rejected_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'schedule_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Schedule date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'schedule_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'project_name',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Project Name',
|
||||
'options': u'Project',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qa_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'QA No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'qa_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Quality Inspection',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Brand',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# 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'stock_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Stock Qty',
|
||||
'oldfieldname': u'stock_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_doctype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Prevdoc Doctype',
|
||||
'oldfieldname': u'prevdoc_doctype',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'PO No',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'prevdoc_docname',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Purchase Order',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'PO Date',
|
||||
'oldfieldname': u'prevdoc_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'rm_supp_cost',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Raw Materials Supplied Cost',
|
||||
'oldfieldname': u'rm_supp_cost',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 2,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_tax_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Item Tax Amount',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'item_tax_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_detail_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Purchase Order Item No',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'prevdoc_detail_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'billed_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Billed Quantity',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'billed_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'valuation_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Valuation Rate',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'valuation_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'80px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_tax_rate',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Item Tax Rate',
|
||||
'oldfieldname': u'item_tax_rate',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 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
|
||||
}
|
||||
]
|
||||
1
stock/doctype/sales_and_purchase_return_tool/__init__.py
Normal file
1
stock/doctype/sales_and_purchase_return_tool/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,225 @@
|
||||
// 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,dt,dn){
|
||||
if(!doc.return_date) set_multiple(dt,dn,{return_date:get_today()});
|
||||
doc.delivery_note_no = '';
|
||||
doc.purchase_receipt_no = '';
|
||||
doc.sales_invoice_no = '';
|
||||
doc.return_type ='';
|
||||
refresh_many(['delivery_note_no', 'sales_invoice_no', 'purchase_receipt_no', 'return_type']);
|
||||
}
|
||||
|
||||
// Link field query
|
||||
//--------------------------------
|
||||
cur_frm.fields_dict.delivery_note_no.get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabDelivery Note`.name FROM `tabDelivery Note` WHERE `tabDelivery Note`.docstatus = 1 AND `tabDelivery Note`.%(key)s LIKE "%s" ORDER BY `tabDelivery Note`.name desc LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.sales_invoice_no.get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabSales Invoice`.name FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1 AND `tabSales Invoice`.%(key)s LIKE "%s" ORDER BY `tabSales Invoice`.name desc LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.purchase_receipt_no.get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabPurchase Receipt`.name FROM `tabPurchase Receipt` WHERE `tabPurchase Receipt`.docstatus = 1 AND `tabPurchase Receipt`.%(key)s LIKE "%s" ORDER BY `tabPurchase Receipt`.name desc LIMIT 50';
|
||||
}
|
||||
|
||||
// Hide/unhide based on return type
|
||||
//----------------------------------
|
||||
cur_frm.cscript.return_type = function(doc, cdt, cdn) {
|
||||
var cp = wn.control_panel;
|
||||
hide_field(['purchase_receipt_no', 'delivery_note_no', 'sales_invoice_no', 'return_details', 'get_items', 'make_excise_invoice', 'make_stock_entry', 'make_debit_note', 'make_credit_note']);
|
||||
|
||||
if(doc.return_type == 'Sales Return') {
|
||||
unhide_field(['delivery_note_no', 'sales_invoice_no', 'get_items', 'return_details', 'make_credit_note', 'make_stock_entry']);
|
||||
|
||||
if(cp.country == 'India') { unhide_field(['make_excise_invoice']); }
|
||||
|
||||
} else if(doc.return_type == 'Purchase Return') {
|
||||
unhide_field(['purchase_receipt_no', 'get_items', 'return_details', 'make_debit_note', 'make_stock_entry']);
|
||||
|
||||
if(cp.country == 'India') { unhide_field(['make_excise_invoice']);}
|
||||
}
|
||||
|
||||
cur_frm.cscript.clear_fields(doc);
|
||||
}
|
||||
|
||||
// Create item table
|
||||
//-------------------------------
|
||||
cur_frm.cscript.get_items = function(doc, cdt, cdn) {
|
||||
flag = 0
|
||||
if(doc.return_type == 'Sales Return') {
|
||||
if (doc.delivery_note_no && doc.sales_invoice_no) {
|
||||
msgprint("You can not enter both Delivery Note No and Sales Invoice No. Please enter any one.");
|
||||
flag = 1;
|
||||
} else if (!doc.delivery_note_no && !doc.sales_invoice_no) {
|
||||
msgprint("Please enter Delivery Note No or Sales Invoice No to proceed");
|
||||
flag = 1;
|
||||
}
|
||||
} else if (doc.return_type == 'Purchase Return' && !doc.purchase_receipt_no) {
|
||||
msgprint("Please enter Purchase Receipt No to proceed");
|
||||
flag = 1;
|
||||
}
|
||||
if (!flag)
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_item_details','', function(r, rt) {
|
||||
refresh_many(['return_details', 'cust_supp', 'cust_supp_name', 'cust_supp_address']);
|
||||
});
|
||||
}
|
||||
|
||||
// Clear fields
|
||||
//-------------------------------
|
||||
cur_frm.cscript.clear_fields = function(doc) {
|
||||
doc.purchase_receipt_no, doc.delivery_note_no, doc.sales_invoice_no = '', '', '';
|
||||
var cl = getchildren('Sales and Purchase Return Item', doc.name, 'return_details')
|
||||
if(cl.length) $c_obj(make_doclist(doc.doctype, doc.name),'clear_return_table','', function(r, rt) {refresh_field('return_details')});
|
||||
refresh_many(['delivery_note_no', 'sales_invoice_no', 'purchase_receipt_no', 'return_details']);
|
||||
}
|
||||
|
||||
// Make Stock Entry
|
||||
//-------------------------------
|
||||
cur_frm.cscript.make_stock_entry = function(doc, cdt, cdn) {
|
||||
var cl = getchildren('Sales and Purchase Return Item', doc.name, 'return_details');
|
||||
if (!cl.length)
|
||||
msgprint("Item table can not be blank. Please click on 'Get Items'.");
|
||||
else if (!cur_frm.cscript.validate_returned_qty(cl)) {
|
||||
se = cur_frm.cscript.map_parent_fields(doc,cdt,cdn);
|
||||
cur_frm.cscript.map_child_fields(cl, se);
|
||||
loaddoc('Stock Entry', se.name);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate returned qty
|
||||
//---------------------------
|
||||
cur_frm.cscript.validate_returned_qty = function(cl) {
|
||||
flag = 0
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
if(cl[i].returned_qty > cl[i].qty) {
|
||||
msgprint("Returned Qty can not be greater than qty. Please check for item: " + cl[i].item_code);
|
||||
flag = 1
|
||||
}
|
||||
}
|
||||
return flag
|
||||
}
|
||||
|
||||
|
||||
// map parent fields of stock entry
|
||||
//----------------------------------
|
||||
cur_frm.cscript.map_parent_fields = function(doc, cdt, cdn) {
|
||||
var se = LocalDB.create('Stock Entry');
|
||||
se = locals['Stock Entry'][se];
|
||||
se.posting_date = dateutil.obj_to_str(new Date());
|
||||
se.transfer_date = dateutil.obj_to_str(new Date());
|
||||
se.fiscal_year = sys_defaults.fiscal_year;
|
||||
se.purpose = doc.return_type;
|
||||
se.remarks = doc.return_type + ' of ' + (doc.delivery_note_no || doc.sales_invoice_no || doc.purchase_receipt_no);
|
||||
if(doc.return_type == 'Sales Return'){
|
||||
se.delivery_note_no = doc.delivery_note_no;
|
||||
se.sales_invoice_no = doc.sales_invoice_no;
|
||||
se.customer = doc.cust_supp_name;
|
||||
se.customer_name = doc.cust_supp_name;
|
||||
se.customer_address = doc.cust_supp_address;
|
||||
}
|
||||
else if(doc.return_type == 'Purchase Return'){
|
||||
se.purchase_receipt_no = doc.purchase_receipt_no;
|
||||
se.supplier = doc.cust_supp_name;
|
||||
se.supplier_name = doc.cust_supp_name;
|
||||
se.supplier_address = doc.cust_supp_address;
|
||||
}
|
||||
return se
|
||||
}
|
||||
|
||||
// map child fields of stock entry
|
||||
//---------------------------------
|
||||
cur_frm.cscript.map_child_fields = function(cl, se) {
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
if (cl[i].returned_qty) {
|
||||
var d1 = LocalDB.add_child(se, 'Stock Entry Detail', 'mtn_details');
|
||||
d1.detail_name = cl[i].detail_name;
|
||||
d1.item_code = cl[i].item_code;
|
||||
d1.description = cl[i].description;
|
||||
d1.transfer_qty = cl[i].returned_qty;
|
||||
d1.qty = cl[i].returned_qty;
|
||||
d1.stock_uom = cl[i].uom;
|
||||
d1.uom = cl[i].uom;
|
||||
d1.conversion_factor = 1;
|
||||
d1.incoming_rate = cl[i].rate;
|
||||
d1.serial_no = cl[i].serial_no;
|
||||
d1.batch_no = cl[i].batch_no;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make excise voucher
|
||||
//-------------------------------
|
||||
cur_frm.cscript.make_excise_invoice = function(doc) {
|
||||
var excise = LocalDB.create('Journal Voucher');
|
||||
excise = locals['Journal Voucher'][excise];
|
||||
excise.voucher_type = 'Excise Voucher';
|
||||
loaddoc('Journal Voucher',excise.name);
|
||||
}
|
||||
// Make debit note
|
||||
//------------------------------
|
||||
cur_frm.cscript.make_debit_note = function(doc) {
|
||||
var doclist = make_doclist(doc.doctype, doc.name);
|
||||
$c('accounts.get_new_jv_details', {
|
||||
doclist: JSON.stringify(doclist),
|
||||
fiscal_year: sys_defaults.fiscal_year
|
||||
}, function(r, rt) {
|
||||
if(!r.exc) {
|
||||
cur_frm.cscript.make_jv(doc, 'Debit Note', r.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Make credit note
|
||||
//------------------------------
|
||||
cur_frm.cscript.make_credit_note = function(doc) {
|
||||
var doclist = make_doclist(doc.doctype, doc.name);
|
||||
$c('accounts.get_new_jv_details', {
|
||||
doclist: JSON.stringify(doclist),
|
||||
fiscal_year: sys_defaults.fiscal_year
|
||||
}, function(r, rt) {
|
||||
if(!r.exc) {
|
||||
cur_frm.cscript.make_jv(doc, 'Credit Note', r.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Make JV
|
||||
//--------------------------------
|
||||
cur_frm.cscript.make_jv = function(doc, dr_or_cr, children) {
|
||||
var jv = LocalDB.create('Journal Voucher');
|
||||
jv = locals['Journal Voucher'][jv];
|
||||
|
||||
jv.voucher_type = dr_or_cr;
|
||||
jv.company = sys_defaults.company;
|
||||
jv.fiscal_year = sys_defaults.fiscal_year;
|
||||
jv.is_opening = 'No';
|
||||
jv.posting_date = dateutil.obj_to_str(new Date());
|
||||
jv.voucher_date = dateutil.obj_to_str(new Date());
|
||||
|
||||
// Add children
|
||||
if(children) {
|
||||
for(var i=0; i<children.length; i++) {
|
||||
var ch = LocalDB.add_child(jv, 'Journal Voucher Detail', 'entries');
|
||||
$.extend(ch, children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
loaddoc('Journal Voucher', jv.name);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
# 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
|
||||
|
||||
# Pull Item Details
|
||||
# ---------------------------
|
||||
def pull_item_details(self):
|
||||
if self.doc.return_type == 'Sales Return':
|
||||
if self.doc.delivery_note_no:
|
||||
det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.uom, t2.export_rate * t3.conversion_rate, t3.customer, t3.customer_name, t3.customer_address, t2.serial_no, t2.batch_no from `tabDelivery Note Packing Item` t1, `tabDelivery Note Item` t2, `tabDelivery Note` t3 where t1.parent = t3.name and t2.parent = t3.name and t1.parent_detail_docname = t2.name and t3.name = '%s' and t3.docstatus = 1" % self.doc.delivery_note_no)
|
||||
elif self.doc.sales_invoice_no:
|
||||
det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.stock_uom, t1.export_rate * t2.conversion_rate, t2.customer, t2.customer_name, t2.customer_address, t1.serial_no from `tabSales Invoice Item` t1, `tabSales Invoice` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.sales_invoice_no)
|
||||
elif self.doc.return_type == 'Purchase Return' and self.doc.purchase_receipt_no:
|
||||
det = sql("select t1.name, t1.item_code, t1.description, t1.received_qty, t1.uom, t1.purchase_rate, t2.supplier, t2.supplier_name, t2.supplier_address, t1.serial_no, t1.batch_no from `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.purchase_receipt_no)
|
||||
|
||||
self.doc.cust_supp = det and det[0][6] or ''
|
||||
self.doc.cust_supp_name = det and det[0][7] or ''
|
||||
self.doc.cust_supp_address = det and det[0][8] or ''
|
||||
self.create_item_table(det)
|
||||
self.doc.save()
|
||||
|
||||
# Create Item Table
|
||||
# -----------------------------
|
||||
def create_item_table(self, det):
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1)
|
||||
for i in det:
|
||||
ch = addchild(self.doc, 'return_details', 'Sales and Purchase Return Item', 1, self.doclist)
|
||||
ch.detail_name = i and i[0] or ''
|
||||
ch.item_code = i and i[1] or ''
|
||||
ch.description = i and i[2] or ''
|
||||
ch.qty = i and flt(i[3]) or 0
|
||||
ch.uom = i and i[4] or ''
|
||||
ch.rate = i and flt(i[5]) or 0
|
||||
ch.serial_no = i and i[9] or ''
|
||||
ch.batch_no = (len(i) == 11) and i[10] or ''
|
||||
ch.save()
|
||||
|
||||
# Clear return table
|
||||
# --------------------------------
|
||||
def clear_return_table(self):
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1)
|
||||
self.doc.save()
|
||||
@@ -0,0 +1,405 @@
|
||||
# DocType, Sales and Purchase Return Tool
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-07-03 13:29:45',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-09-17 10:55:11',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'wasim@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocType',
|
||||
'is_transaction_doc': 0,
|
||||
'issingle': 1,
|
||||
'istable': 0,
|
||||
'menu_index': 1,
|
||||
'module': u'Stock',
|
||||
u'name': u'__common__',
|
||||
'parent_node': u'Materials',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 1,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Sales and Purchase Return Tool',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Sales and Purchase Return Tool',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Sales and Purchase Return Tool
|
||||
{
|
||||
u'doctype': u'DocType',
|
||||
u'name': u'Sales and Purchase Return Tool'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'return_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Return Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'return_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'return_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Return Type',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'return_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nSales Return\nPurchase Return',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'delivery_note_no',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Delivery Note No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'delivery_note_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Delivery Note',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'sales_invoice_no',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Sales Invoice No',
|
||||
'options': u'Sales Invoice',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'purchase_receipt_no',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Purchase Receipt No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'purchase_receipt_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Purchase Receipt',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'cust_supp',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Customer/Supplier',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'cust_supp_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Cust/Supp Name',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'cust_supp_address',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 1,
|
||||
'label': u'Cust/Supp Address',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'get_items',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 1,
|
||||
'label': u'Get Items',
|
||||
'oldfieldtype': u'Button',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'return_details',
|
||||
'fieldtype': u'Table',
|
||||
'hidden': 1,
|
||||
'label': u'Sales and Purchase Return Items',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'return_details',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Sales and Purchase Return Item',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'make_stock_entry',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 1,
|
||||
'label': u'Make Stock Entry',
|
||||
'oldfieldtype': u'Button',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'make_excise_invoice',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 1,
|
||||
'label': u'Make Excise Invoice',
|
||||
'oldfieldtype': u'Button',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'make_credit_note',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 1,
|
||||
'label': u'Make Credit Note',
|
||||
'oldfieldtype': u'Button',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'make_debit_note',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 1,
|
||||
'label': u'Make Debit Note',
|
||||
'oldfieldtype': u'Button',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Accounts Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Accounts Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Purchase Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Purchase User',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Accounts User',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Accounts User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Purchase User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Purchase Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
}
|
||||
]
|
||||
1
stock/doctype/sales_bom/__init__.py
Normal file
1
stock/doctype/sales_bom/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
39
stock/doctype/sales_bom/sales_bom.js
Normal file
39
stock/doctype/sales_bom/sales_bom.js
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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.refresh = function(doc, cdt, cdn) {
|
||||
cur_frm.toggle_enable('new_item_code', doc.__islocal);
|
||||
if(!doc.__islocal) {
|
||||
cur_frm.add_custom_button("Check for Duplicates", function() {
|
||||
cur_frm.call_server('check_duplicate', 1)
|
||||
}, 'icon-search')
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.new_item_code.get_query = function() {
|
||||
return 'select name, description from tabItem where is_stock_item="No" and is_sales_item="Yes"\
|
||||
and name not in (select name from `tabSales BOM`)\
|
||||
and `%(key)s` like "%s"'
|
||||
}
|
||||
cur_frm.fields_dict.new_item_code.query_description = 'Select Item where "Is Stock Item" is "No" \
|
||||
and "Is Sales Item" is "Yes" and there is no other Sales BOM';
|
||||
|
||||
cur_frm.cscript.item_code = function(doc, dt, dn) {
|
||||
var d = locals[dt][dn];
|
||||
if (d.item_code){
|
||||
get_server_fields('get_item_details', d.item_code, 'sales_bom_items', doc ,dt, dn, 1);
|
||||
}
|
||||
}
|
||||
85
stock/doctype/sales_bom/sales_bom.py
Normal file
85
stock/doctype/sales_bom/sales_bom.py
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/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes.utils import flt
|
||||
from webnotes.model.utils import getlist
|
||||
|
||||
class DocType:
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d,dl
|
||||
|
||||
def autoname(self):
|
||||
self.doc.name = self.doc.new_item_code
|
||||
|
||||
def validate(self):
|
||||
# check for duplicate
|
||||
self.check_duplicate()
|
||||
self.validate_main_item()
|
||||
|
||||
def validate_main_item(self):
|
||||
"""main item must have Is Stock Item as No and Is Sales Item as Yes"""
|
||||
if not webnotes.conn.sql("""select name from tabItem where name=%s and
|
||||
ifnull(is_stock_item,'')='No' and ifnull(is_sales_item,'')='Yes'""", self.doc.new_item_code):
|
||||
webnotes.msgprint("""Parent Item %s is either a Stock Item or a not a Sales Item""",
|
||||
raise_exception=1)
|
||||
|
||||
def get_item_details(self, name):
|
||||
det = webnotes.conn.sql("""select description, stock_uom from `tabItem`
|
||||
where name = %s""", name)
|
||||
rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||
where price_list_name = %s and parent = %s
|
||||
and ref_currency = %s""", (self.doc.price_list, name, self.doc.currency))
|
||||
return {
|
||||
'description' : det and det[0][0] or '',
|
||||
'uom': det and det[0][1] or '',
|
||||
'rate': rate and flt(rate[0][0]) or 0.00
|
||||
}
|
||||
|
||||
def check_duplicate(self, finder=0):
|
||||
il = getlist(self.doclist, "sales_bom_items")
|
||||
if not il:
|
||||
webnotes.msgprint("Add atleast one item")
|
||||
return
|
||||
|
||||
# get all Sales BOM that have the first item
|
||||
sbl = webnotes.conn.sql("""select distinct parent from `tabSales BOM Item` where item_code=%s
|
||||
and parent != %s and docstatus != 2""", (il[0].item_code, self.doc.name))
|
||||
|
||||
# check all siblings
|
||||
sub_items = [[d.item_code, flt(d.qty)] for d in il]
|
||||
|
||||
for s in sbl:
|
||||
t = webnotes.conn.sql("""select item_code, qty from `tabSales BOM Item` where parent=%s and
|
||||
docstatus != 2""", s[0])
|
||||
t = [[d[0], flt(d[1])] for d in t]
|
||||
|
||||
if self.has_same_items(sub_items, t):
|
||||
webnotes.msgprint("%s has the same Sales BOM details" % s[0])
|
||||
raise Exception
|
||||
if finder:
|
||||
webnotes.msgprint("There is no Sales BOM present with the following Combination.")
|
||||
|
||||
def has_same_items(self, l1, l2):
|
||||
if len(l1)!=len(l2): return 0
|
||||
for l in l2:
|
||||
if l not in l1:
|
||||
return 0
|
||||
for l in l1:
|
||||
if l not in l2:
|
||||
return 0
|
||||
return 1
|
||||
162
stock/doctype/sales_bom/sales_bom.txt
Normal file
162
stock/doctype/sales_bom/sales_bom.txt
Normal file
@@ -0,0 +1,162 @@
|
||||
# DocType, Sales BOM
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-07-03 13:30:44',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-12 18:00:16',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1322549701',
|
||||
'allow_trash': 1,
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have "Is Stock Item" as "No" and "Is Sales Item" as "Yes".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.\n\nNote: BOM = Bill of Materials',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'is_submittable': 0,
|
||||
'module': u'Stock',
|
||||
'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'Sales BOM',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales BOM',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1,
|
||||
'submit': 0
|
||||
},
|
||||
|
||||
# DocType, Sales BOM
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales BOM'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material User',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material User',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_section',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Sales BOM Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The Item that represents the Package. This Item must have "Is Stock Item" as "No" and "Is Sales Item" as "Yes"',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'new_item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Parent Item',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'new_item_code',
|
||||
'oldfieldtype': u'Data',
|
||||
'options': u'Item',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'List items that form the package.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_section',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Package Items'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'sales_bom_items',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Sales BOM Items',
|
||||
'oldfieldname': u'sales_bom_items',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Sales BOM Item',
|
||||
'reqd': 1
|
||||
}
|
||||
]
|
||||
1
stock/doctype/sales_bom_item/__init__.py
Normal file
1
stock/doctype/sales_bom_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
102
stock/doctype/sales_bom_item/sales_bom_item.txt
Normal file
102
stock/doctype/sales_bom_item/sales_bom_item.txt
Normal file
@@ -0,0 +1,102 @@
|
||||
# DocType, Sales BOM Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-07-03 13:30:46',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-11 18:56:27',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'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 BOM Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Sales BOM Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales BOM Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'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'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# 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
|
||||
}
|
||||
]
|
||||
1
stock/doctype/serial_no/__init__.py
Normal file
1
stock/doctype/serial_no/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
70
stock/doctype/serial_no/serial_no.js
Normal file
70
stock/doctype/serial_no/serial_no.js
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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) {
|
||||
if(!doc.status) set_multiple(cdt, cdn, {status:'In Store'});
|
||||
if(doc.__islocal) hide_field(['supplier_name','address_display'])
|
||||
}
|
||||
|
||||
|
||||
// ************************************** refresh ***************************************************
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
if(!doc.__islocal) {
|
||||
flds = ['item_code', 'warehouse', 'purchase_document_type', 'purchase_document_no', 'purchase_date', 'purchase_time', 'purchase_rate', 'supplier']
|
||||
for(i=0;i<flds.length;i++)
|
||||
set_field_permlevel(flds[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************** triggers **************************************************
|
||||
|
||||
// item details
|
||||
// -------------
|
||||
cur_frm.add_fetch('item_code', 'item_name', 'item_name')
|
||||
cur_frm.add_fetch('item_code', 'item_group', 'item_group')
|
||||
cur_frm.add_fetch('item_code', 'brand', 'brand')
|
||||
cur_frm.add_fetch('item_code', 'description', 'description')
|
||||
cur_frm.add_fetch('item_code', 'warranty_period', 'warranty_period')
|
||||
|
||||
// customer
|
||||
// ---------
|
||||
cur_frm.add_fetch('customer', 'customer_name', 'customer_name')
|
||||
cur_frm.add_fetch('customer', 'address', 'delivery_address')
|
||||
cur_frm.add_fetch('customer', 'territory', 'territory')
|
||||
|
||||
// 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';
|
||||
}
|
||||
|
||||
// Supplier
|
||||
//-------------
|
||||
cur_frm.cscript.supplier = function(doc,dt,dn) {
|
||||
if(doc.supplier) get_server_fields('get_default_supplier_address', JSON.stringify({supplier: doc.supplier}),'', doc, dt, dn, 1);
|
||||
if(doc.supplier) unhide_field(['supplier_name','address_display']);
|
||||
}
|
||||
|
||||
//item code
|
||||
//----------
|
||||
cur_frm.fields_dict['item_code'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabItem`.`name`,`tabItem`.`description` FROM `tabItem` \
|
||||
WHERE `tabItem`.`docstatus`!= 2 AND ifnull(`tabItem`.`has_serial_no`, "No") = "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" ORDER BY `tabItem`.`name` ASC LIMIT 50';
|
||||
}
|
||||
123
stock/doctype/serial_no/serial_no.py
Normal file
123
stock/doctype/serial_no/serial_no.py
Normal file
@@ -0,0 +1,123 @@
|
||||
# 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 cint, flt, cstr, getdate, nowdate
|
||||
import datetime
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
msgprint = webnotes.msgprint
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
def validate_amc_status(self):
|
||||
"""
|
||||
validate amc status
|
||||
"""
|
||||
if (self.doc.maintenance_status == 'Out of AMC' and self.doc.amc_expiry_date and getdate(self.doc.amc_expiry_date) >= datetime.date.today()) or (self.doc.maintenance_status == 'Under AMC' and (not self.doc.amc_expiry_date or getdate(self.doc.amc_expiry_date) < datetime.date.today())):
|
||||
msgprint("AMC expiry date and maintenance status mismatch. Please verify", raise_exception=1)
|
||||
|
||||
def validate_warranty_status(self):
|
||||
"""
|
||||
validate warranty status
|
||||
"""
|
||||
if (self.doc.maintenance_status == 'Out of Warranty' and self.doc.warranty_expiry_date and getdate(self.doc.warranty_expiry_date) >= datetime.date.today()) or (self.doc.maintenance_status == 'Under Warranty' and (not self.doc.warranty_expiry_date or getdate(self.doc.warranty_expiry_date) < datetime.date.today())):
|
||||
msgprint("Warranty expiry date and maintenance status mismatch. Please verify", raise_exception=1)
|
||||
|
||||
|
||||
def validate_warehouse(self):
|
||||
if self.doc.status=='In Store' and not self.doc.warehouse:
|
||||
msgprint("Warehouse is mandatory if this Serial No is <b>In Store</b>", raise_exception=1)
|
||||
|
||||
def validate_item(self):
|
||||
"""
|
||||
Validate whether serial no is required for this item
|
||||
"""
|
||||
item = sql("select name, has_serial_no from tabItem where name = '%s'" % self.doc.item_code)
|
||||
if not item:
|
||||
msgprint("Item is not exists in the system", raise_exception=1)
|
||||
elif item[0][1] == 'No':
|
||||
msgprint("To proceed please select 'Yes' in 'Has Serial No' in Item master: '%s'" % self.doc.item_code, raise_exception=1)
|
||||
|
||||
|
||||
# ---------
|
||||
# validate
|
||||
# ---------
|
||||
def validate(self):
|
||||
self.validate_warranty_status()
|
||||
self.validate_amc_status()
|
||||
self.validate_warehouse()
|
||||
self.validate_item()
|
||||
|
||||
def on_update(self):
|
||||
if self.doc.warehouse and self.doc.status == 'In Store' and cint(self.doc.sle_exists) == 0 and \
|
||||
not sql("select name from `tabStock Ledger Entry` where serial_no = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name):
|
||||
self.make_stock_ledger_entry(1)
|
||||
webnotes.conn.set(self.doc, 'sle_exists', 1)
|
||||
|
||||
|
||||
def make_stock_ledger_entry(self, qty):
|
||||
from webnotes.model.code import get_obj
|
||||
values = [{
|
||||
'item_code' : self.doc.item_code,
|
||||
'warehouse' : self.doc.warehouse,
|
||||
'transaction_date' : nowdate(),
|
||||
'posting_date' : self.doc.purchase_date or (self.doc.creation and self.doc.creation.split(' ')[0]) or nowdate(),
|
||||
'posting_time' : self.doc.purchase_time or '00:00',
|
||||
'voucher_type' : 'Serial No',
|
||||
'voucher_no' : self.doc.name,
|
||||
'voucher_detail_no' : '',
|
||||
'actual_qty' : qty,
|
||||
'stock_uom' : webnotes.conn.get_value('Item', self.doc.item_code, 'stock_uom'),
|
||||
'incoming_rate' : self.doc.purchase_rate,
|
||||
'company' : self.doc.company,
|
||||
'fiscal_year' : self.doc.fiscal_year,
|
||||
'is_cancelled' : 'No', # is_cancelled is always 'No' because while deleted it can not find creation entry if it not created directly, voucher no != serial no
|
||||
'batch_no' : '',
|
||||
'serial_no' : self.doc.name
|
||||
}]
|
||||
get_obj('Stock Ledger', 'Stock Ledger').update_stock(values)
|
||||
|
||||
|
||||
# ---------
|
||||
# on trash
|
||||
# ---------
|
||||
def on_trash(self):
|
||||
if self.doc.status == 'Delivered':
|
||||
msgprint("Cannot trash Serial No : %s as it is already Delivered" % (self.doc.name), raise_exception = 1)
|
||||
elif self.doc.status == 'In Store':
|
||||
webnotes.conn.set(self.doc, 'status', 'Not in Use')
|
||||
self.make_stock_ledger_entry(-1)
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
self.on_trash()
|
||||
|
||||
# -----------
|
||||
# on restore
|
||||
# -----------
|
||||
def on_restore(self):
|
||||
self.make_stock_ledger_entry(1)
|
||||
730
stock/doctype/serial_no/serial_no.txt
Normal file
730
stock/doctype/serial_no/serial_no.txt
Normal file
@@ -0,0 +1,730 @@
|
||||
# DocType, Serial No
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-04-23 16:00:23',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-04-26 13:01:57',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1325570647',
|
||||
'allow_attach': 1,
|
||||
'allow_trash': 1,
|
||||
'autoname': u'field:serial_no',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'search_fields': u'item_code,status',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'Item Code: %(item_code)s, Warehouse: %(warehouse)s',
|
||||
'tag_fields': u'status',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Serial No',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Serial No',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Serial No
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Serial No'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material Master Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Master Manager'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Details',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'In Store',
|
||||
'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'\nIn Store\nDelivered\nNot in Use\nPurchase Returned',
|
||||
'permlevel': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 0,
|
||||
'label': u'Serial No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'serial_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'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': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Item Name',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'in_filter': 1,
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_group',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 0,
|
||||
'label': u'Item Group',
|
||||
'oldfieldname': u'item_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item Group',
|
||||
'permlevel': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 0,
|
||||
'label': u'Brand',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Purchase Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_document_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Purchase Document Type',
|
||||
'no_copy': 1,
|
||||
'options': u'\nPurchase Receipt\nStock Entry',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_document_no',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'label': u'Purchase Document No',
|
||||
'no_copy': 1,
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_date',
|
||||
'fieldtype': u'Date',
|
||||
'in_filter': 1,
|
||||
'label': u'Purchase Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'purchase_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_time',
|
||||
'fieldtype': u'Time',
|
||||
'label': u'Incoming Time',
|
||||
'no_copy': 1,
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Incoming Rate',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'purchase_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Warehouse',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Supplier',
|
||||
'no_copy': 1,
|
||||
'options': u'Supplier',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Supplier Name',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'address_display',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Supplier Address',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Delivery Details',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break4',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_document_type',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Delivery Document Type',
|
||||
'no_copy': 1,
|
||||
'options': u'\nDelivery Note\nSales Invoice\nStock Entry',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_document_no',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Delivery Document No',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Customer Address',
|
||||
'oldfieldname': u'customer_address',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Delivery Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'delivery_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_time',
|
||||
'fieldtype': u'Time',
|
||||
'label': u'Delivery Time',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'is_cancelled',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 1,
|
||||
'label': u'Is Cancelled',
|
||||
'oldfieldname': u'is_cancelled',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nYes\nNo',
|
||||
'permlevel': 0,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break5',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Customer',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Name',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'customer_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_address',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Delivery Address',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Territory',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'territory',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Territory',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warranty_amc_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Warranty / AMC Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break6',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'maintenance_status',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Maintenance Status',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'maintenance_status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nUnder Warranty\nOut of Warranty\nUnder AMC\nOut of AMC',
|
||||
'permlevel': 0,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warranty_period',
|
||||
'fieldtype': u'Int',
|
||||
'label': u'Warranty Period (Days)',
|
||||
'oldfieldname': u'warranty_period',
|
||||
'oldfieldtype': u'Int',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break7',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warranty_expiry_date',
|
||||
'fieldtype': u'Date',
|
||||
'in_filter': 1,
|
||||
'label': u'Warranty Expiry Date',
|
||||
'oldfieldname': u'warranty_expiry_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amc_expiry_date',
|
||||
'fieldtype': u'Date',
|
||||
'in_filter': 1,
|
||||
'label': u'AMC Expiry Date',
|
||||
'oldfieldname': u'amc_expiry_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'search_index': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'more_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'More Info',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no_details',
|
||||
'fieldtype': u'Text Editor',
|
||||
'label': u'Serial No Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'options': u'link:Company',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 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'file_list',
|
||||
'fieldtype': u'Text',
|
||||
'hidden': 1,
|
||||
'label': u'File List',
|
||||
'no_copy': 1,
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'sle_exists',
|
||||
'fieldtype': u'Check',
|
||||
'hidden': 1,
|
||||
'label': u'SLE Exists',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
}
|
||||
]
|
||||
28
stock/doctype/serial_no/serial_no_list.js
Normal file
28
stock/doctype/serial_no/serial_no_list.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// render
|
||||
wn.doclistviews['Serial No'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabSerial No`.item_code",
|
||||
"`tabSerial No`.item_name",
|
||||
"`tabSerial No`.status",
|
||||
"`tabSerial No`.warehouse",
|
||||
]);
|
||||
this.stats = this.stats.concat(['company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
data.item_name = data.item_name ? data.item_name : data.item_code;
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content:'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '30%', content:'item_name+tags'},
|
||||
{width: '15%', content:'status'},
|
||||
{width: '20%', content:'warehouse', css: {'color': '#777'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
||||
]
|
||||
});
|
||||
1
stock/doctype/stock_entry/__init__.py
Normal file
1
stock/doctype/stock_entry/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
232
stock/doctype/stock_entry/stock_entry.js
Normal file
232
stock/doctype/stock_entry/stock_entry.js
Normal file
@@ -0,0 +1,232 @@
|
||||
// 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.onload = function(doc, cdt, cdn) {
|
||||
if (!doc.posting_date) doc.posting_date = dateutil.obj_to_str(new Date());
|
||||
if (!doc.transfer_date) doc.transfer_date = dateutil.obj_to_str(new Date());
|
||||
if(!doc.purpose) set_multiple(cdt, cdn, {purpose:'Material Issue'});
|
||||
cfn_set_fields(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
var cfn_set_fields = function(doc, cdt, cdn) {
|
||||
lst = ['supplier','supplier_name','supplier_address','customer','customer_name','customer_address'];
|
||||
if (in_list(['Material Issue', 'Material Transfer', 'Material Receipt', 'Sales Return', 'Purchase Return', 'Production Order', 'Subcontracting', 'Other'], doc.purpose)) {
|
||||
hide_field(lst);
|
||||
$(cur_frm.fields_dict.contact_section.row.wrapper).toggle(false);
|
||||
} else unhide_field(lst);
|
||||
|
||||
|
||||
if (doc.purpose == 'Production Order' || doc.purpose == 'Other'){
|
||||
unhide_field('get_items');
|
||||
hide_field(['from_warehouse', 'to_warehouse','purchase_receipt_no','delivery_note_no', 'sales_invoice_no','warehouse_html', 'transporter', 'is_excisable_goods', 'excisable_goods']);
|
||||
if (doc.purpose=='Production Order') unhide_field(['production_order', 'process']);
|
||||
else hide_field(['production_order', 'process']);
|
||||
|
||||
doc.from_warehouse = '';
|
||||
doc.to_warehouse = '';
|
||||
refresh_field(['from_warehosue', 'to_warehouse']);
|
||||
if (doc.process == 'Backflush' || doc.purpose == 'Other'){
|
||||
unhide_field('fg_completed_qty');
|
||||
}
|
||||
else{
|
||||
hide_field('fg_completed_qty');
|
||||
doc.fg_completed_qty = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
unhide_field(['from_warehouse', 'to_warehouse']);
|
||||
hide_field(['production_order', 'process', 'get_items', 'fg_completed_qty','purchase_receipt_no','delivery_note_no', 'sales_invoice_no']);
|
||||
doc.production_order = '';
|
||||
doc.process = '';
|
||||
doc.fg_completed_qty = 0;
|
||||
}
|
||||
|
||||
|
||||
if(doc.purpose == 'Purchase Return'){
|
||||
doc.customer=doc.customer_name = doc.customer_address=doc.delivery_note_no=doc.sales_invoice_no='';
|
||||
unhide_field(['supplier','supplier_name','supplier_address','purchase_receipt_no']);
|
||||
$(cur_frm.fields_dict.contact_section.row.wrapper).toggle(true);
|
||||
}
|
||||
else if(doc.purpose == 'Sales Return'){
|
||||
doc.supplier=doc.supplier_name = doc.supplier_address=doc.purchase_receipt_no='';
|
||||
unhide_field(['customer','customer_name','customer_address','delivery_note_no', 'sales_invoice_no']);
|
||||
$(cur_frm.fields_dict.contact_section.row.wrapper).toggle(true);
|
||||
} else{
|
||||
doc.customer=doc.customer_name=doc.customer_address=doc.delivery_note_no=doc.sales_invoice_no='';
|
||||
doc.supplier=doc.supplier_name = doc.supplier_address=doc.purchase_receipt_no='';
|
||||
}
|
||||
refresh_many(lst);
|
||||
}
|
||||
|
||||
//Refresh
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
//India related
|
||||
excise_flds = ['is_excisable_goods', 'excisable_goods', 'under_rule']
|
||||
if(wn.control_panel.country == 'India') unhide_field(excise_flds);
|
||||
else hide_field(excise_flds);
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.delivery_note_no = function(doc,cdt,cdn){
|
||||
if(doc.delivery_note_no) get_server_fields('get_cust_values','','',doc,cdt,cdn,1);
|
||||
}
|
||||
|
||||
cur_frm.cscript.sales_invoice_no = function(doc,cdt,cdn){
|
||||
if(doc.sales_invoice_no) get_server_fields('get_cust_values','','',doc,cdt,cdn,1);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer = function(doc,cdt,cdn){
|
||||
if(doc.customer) get_server_fields('get_cust_addr','','',doc,cdt,cdn,1);
|
||||
}
|
||||
|
||||
cur_frm.cscript.purchase_receipt_no = function(doc,cdt,cdn){
|
||||
if(doc.purchase_receipt_no) get_server_fields('get_supp_values','','',doc,cdt,cdn,1);
|
||||
}
|
||||
|
||||
cur_frm.cscript.supplier = function(doc,cdt,cdn){
|
||||
if(doc.supplier) get_server_fields('get_supp_addr','','',doc,cdt,cdn,1);
|
||||
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['production_order'].get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabProduction Order`.`name` FROM `tabProduction Order` WHERE `tabProduction Order`.`docstatus` = 1 AND `tabProduction Order`.`qty` > ifnull(`tabProduction Order`.`produced_qty`,0) AND `tabProduction Order`.`name` like "%s" ORDER BY `tabProduction Order`.`name` DESC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.purpose = function(doc, cdt, cdn) {
|
||||
cfn_set_fields(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.process = function(doc, cdt, cdn) {
|
||||
cfn_set_fields(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
//
|
||||
// item code - only if quantity present in source warehosue
|
||||
//
|
||||
var fld = cur_frm.fields_dict['mtn_details'].grid.get_field('item_code');
|
||||
fld.query_description = "If Source Warehouse is selected, only items present in the warehouse with actual qty > 0 will be selected"
|
||||
fld.get_query = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
|
||||
if(d.s_warehouse) {
|
||||
return 'SELECT tabItem.name, tabItem.description, tabBin.actual_qty '
|
||||
+'FROM tabItem, tabBin '
|
||||
+'WHERE tabItem.name = tabBin.item_code '
|
||||
+'AND ifnull(`tabBin`.`actual_qty`,0) > 0 '
|
||||
+'AND tabBin.warehouse="'+ d.s_warehouse +'" '
|
||||
+'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" '
|
||||
+'ORDER BY tabItem.name ASC '
|
||||
+'LIMIT 50'
|
||||
} else {
|
||||
return 'SELECT tabItem.name, tabItem.description '
|
||||
+'FROM tabItem '
|
||||
+'WHERE 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" '
|
||||
+'ORDER BY tabItem.name ASC '
|
||||
+'LIMIT 50'
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// copy over source and target warehouses
|
||||
//
|
||||
cur_frm.fields_dict['mtn_details'].grid.onrowadd = function(doc, cdt, cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
if(!d.s_warehouse && doc.from_warehouse) {
|
||||
d.s_warehouse = doc.from_warehouse
|
||||
refresh_field('s_warehouse', cdn, 'mtn_details')
|
||||
}
|
||||
if(!d.t_warehouse && doc.to_warehouse) {
|
||||
d.t_warehouse = doc.to_warehouse
|
||||
refresh_field('t_warehouse', cdn, 'mtn_details')
|
||||
}
|
||||
}
|
||||
|
||||
//========================= Overloaded query for link batch_no =============================================================
|
||||
cur_frm.fields_dict['mtn_details'].grid.get_field('batch_no').get_query= function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.item_code){
|
||||
return "SELECT tabBatch.name, tabBatch.description FROM tabBatch WHERE tabBatch.docstatus != 2 AND tabBatch.item = '"+ d.item_code +"' AND `tabBatch`.`name` like '%s' ORDER BY `tabBatch`.`name` DESC LIMIT 50"
|
||||
}
|
||||
else{
|
||||
alert("Please enter Item Code.");
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================================
|
||||
|
||||
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
// get values
|
||||
args = {
|
||||
'item_code' : d.item_code,
|
||||
'warehouse' : cstr(d.s_warehouse),
|
||||
'transfer_qty' : d.transfer_qty,
|
||||
'serial_no' : d.serial_no
|
||||
};
|
||||
get_server_fields('get_item_details',JSON.stringify(args),'mtn_details',doc,cdt,cdn,1);
|
||||
}
|
||||
|
||||
//==================================================================================================================
|
||||
|
||||
cur_frm.cscript.transfer_qty = function(doc,cdt,cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (doc.from_warehouse && (flt(d.transfer_qty) > flt(d.actual_qty))) {
|
||||
alert("Transfer Quantity is more than Available Qty");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==================================================================================================================
|
||||
|
||||
cur_frm.cscript.qty = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
set_multiple('Stock Entry Detail', d.name, {'transfer_qty': flt(d.qty) * flt(d.conversion_factor)}, 'mtn_details');
|
||||
refresh_field('mtn_details');
|
||||
}
|
||||
|
||||
//==================================================================================================================
|
||||
|
||||
cur_frm.cscript.uom = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.uom && d.item_code){
|
||||
var arg = {'item_code':d.item_code, 'uom':d.uom, 'qty':d.qty}
|
||||
get_server_fields('get_uom_details',JSON.stringify(arg),'mtn_details', doc, cdt, cdn, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================================
|
||||
//validate
|
||||
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.validate_items(doc);
|
||||
}
|
||||
|
||||
//==================================================================================================================
|
||||
//validate items
|
||||
cur_frm.cscript.validate_items = function(doc) {
|
||||
cl = getchildren('Stock Entry Detail',doc.name,'mtn_details');
|
||||
if (!cl.length) {
|
||||
alert("Item table can not be blank");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
538
stock/doctype/stock_entry/stock_entry.py
Normal file
538
stock/doctype/stock_entry/stock_entry.py
Normal file
@@ -0,0 +1,538 @@
|
||||
# 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, delete_doc
|
||||
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.item_dict = {}
|
||||
self.fname = 'mtn_details'
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# get item details
|
||||
# ----------------
|
||||
def get_item_details(self, arg):
|
||||
import json
|
||||
arg, actual_qty, in_rate = json.loads(arg), 0, 0
|
||||
|
||||
item = sql("select stock_uom, description, item_name from `tabItem` where name = %s and (ifnull(end_of_life,'')='' or end_of_life ='0000-00-00' or end_of_life > now())", (arg.get('item_code')), as_dict = 1)
|
||||
if not item:
|
||||
msgprint("Item is not active", raise_exception=1)
|
||||
|
||||
if arg.get('warehouse'):
|
||||
actual_qty = self.get_as_on_stock(arg.get('item_code'), arg.get('warehouse'), self.doc.posting_date, self.doc.posting_time)
|
||||
in_rate = self.get_incoming_rate(arg.get('item_code'), arg.get('warehouse'), self.doc.posting_date, self.doc.posting_time, arg.get('transfer_qty'), arg.get('serial_no')) or 0
|
||||
|
||||
ret = {
|
||||
'uom' : item and item[0]['stock_uom'] or '',
|
||||
'stock_uom' : item and item[0]['stock_uom'] or '',
|
||||
'description' : item and item[0]['description'] or '',
|
||||
'item_name' : item and item[0]['item_name'] or '',
|
||||
'actual_qty' : actual_qty,
|
||||
'qty' : 0,
|
||||
'transfer_qty' : 0,
|
||||
'incoming_rate' : in_rate,
|
||||
'conversion_factor' : 1,
|
||||
'batch_no' : ''
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
# Get UOM Details
|
||||
# ----------------
|
||||
def get_uom_details(self, arg = ''):
|
||||
arg, ret = eval(arg), {}
|
||||
uom = sql("select conversion_factor from `tabUOM Conversion Detail` where parent = %s and uom = %s", (arg['item_code'],arg['uom']), as_dict = 1)
|
||||
if not uom:
|
||||
msgprint("There is no Conversion Factor for UOM '%s' in Item '%s'" % (arg['uom'], arg['item_code']))
|
||||
ret = {'uom' : ''}
|
||||
else:
|
||||
ret = {
|
||||
'conversion_factor' : flt(uom[0]['conversion_factor']),
|
||||
'transfer_qty' : flt(arg['qty']) * flt(uom[0]['conversion_factor']),
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
# get stock and incoming rate on posting date
|
||||
# ---------------------------------------------
|
||||
def get_stock_and_rate(self, bom_no = ''):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
# assign parent warehouse
|
||||
d.s_warehouse = cstr(d.s_warehouse) or self.doc.purpose != 'Production Order' and self.doc.from_warehouse or ''
|
||||
d.t_warehouse = cstr(d.t_warehouse) or self.doc.purpose != 'Production Order' and self.doc.to_warehouse or ''
|
||||
|
||||
# get current stock at source warehouse
|
||||
d.actual_qty = d.s_warehouse and self.get_as_on_stock(d.item_code, d.s_warehouse, self.doc.posting_date, self.doc.posting_time) or 0
|
||||
|
||||
# get incoming rate
|
||||
if not flt(d.incoming_rate):
|
||||
d.incoming_rate = self.get_incoming_rate(d.item_code, d.s_warehouse, self.doc.posting_date, self.doc.posting_time, d.transfer_qty, d.serial_no, d.fg_item, d.bom_no or bom_no)
|
||||
|
||||
|
||||
# Get stock qty on any date
|
||||
# ---------------------------
|
||||
def get_as_on_stock(self, item, wh, dt, tm):
|
||||
bin = sql("select name from tabBin where item_code = %s and warehouse = %s", (item, wh))
|
||||
bin_id = bin and bin[0][0] or ''
|
||||
prev_sle = bin_id and get_obj('Bin', bin_id).get_prev_sle(dt, tm) or {}
|
||||
qty = flt(prev_sle.get('bin_aqat', 0))
|
||||
return qty
|
||||
|
||||
|
||||
# Get incoming rate
|
||||
# -------------------
|
||||
def get_incoming_rate(self, item, wh, dt, tm, qty = 0, serial_no = '', fg_item = 0, bom_no = ''):
|
||||
in_rate = 0
|
||||
if fg_item and bom_no:
|
||||
# re-calculate cost for production item from bom
|
||||
get_obj('BOM Control').calculate_cost(bom_no)
|
||||
bom_obj = get_obj('BOM', bom_no)
|
||||
in_rate = flt(bom_obj.doc.total_cost) / (flt(bom_obj.doc.quantity) or 1)
|
||||
elif wh:
|
||||
in_rate = get_obj('Valuation Control').get_incoming_rate(dt, tm, item, wh, qty, serial_no)
|
||||
|
||||
return in_rate
|
||||
|
||||
|
||||
|
||||
def make_items_dict(self, items_list):
|
||||
"""makes dict of unique items with it's qty"""
|
||||
for i in items_list:
|
||||
if self.item_dict.has_key(i[0]):
|
||||
self.item_dict[i[0]][0] = flt(self.item_dict[i[0]][0]) + flt(i[1])
|
||||
else:
|
||||
self.item_dict[i[0]] = [flt(i[1]), cstr(i[2]), cstr(i[3])]
|
||||
|
||||
|
||||
|
||||
def update_only_remaining_qty(self):
|
||||
""" Only pending raw material to be issued to shop floor """
|
||||
already_issued_item = {}
|
||||
for t in sql("""select t1.item_code, sum(t1.qty) from `tabStock Entry Detail` t1, `tabStock Entry` t2
|
||||
where t1.parent = t2.name and t2.production_order = %s and t2.process = 'Material Transfer'
|
||||
and t2.docstatus = 1 group by t1.item_code""", self.doc.production_order):
|
||||
already_issued_item[t[0]] = flt(t[1])
|
||||
|
||||
for d in self.item_dict.keys():
|
||||
self.item_dict[d][0] -= already_issued_item.get(d, 0)
|
||||
if self.item_dict[d][0] <= 0:
|
||||
del self.item_dict[d]
|
||||
|
||||
|
||||
|
||||
def get_raw_materials(self, bom_no, fg_qty, consider_sa_items_as_rm):
|
||||
"""
|
||||
get all items from flat bom except
|
||||
child items of sub-contracted and sub assembly items
|
||||
and sub assembly items itself.
|
||||
"""
|
||||
if consider_sa_items_as_rm == 'Yes':
|
||||
# Get all raw materials considering SA items as raw materials,
|
||||
# so no childs of SA items
|
||||
fl_bom_sa_items = sql("""
|
||||
select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom
|
||||
from `tabBOM Item`
|
||||
where parent = '%s' and docstatus < 2
|
||||
group by item_code
|
||||
""" % (fg_qty, bom_no))
|
||||
|
||||
self.make_items_dict(fl_bom_sa_items)
|
||||
|
||||
else:
|
||||
# get all raw materials with sub assembly childs
|
||||
fl_bom_sa_child_item = sql("""
|
||||
select
|
||||
item_code,ifnull(sum(qty_consumed_per_unit),0)*%s as qty,description,stock_uom
|
||||
from
|
||||
(
|
||||
select distinct fb.name, fb.description, fb.item_code, fb.qty_consumed_per_unit, fb.stock_uom
|
||||
from `tabBOM Explosion Item` fb,`tabItem` it
|
||||
where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No'
|
||||
and ifnull(it.is_sub_contracted_item, 'No') = 'No' and fb.docstatus<2 and fb.parent=%s
|
||||
) a
|
||||
group by item_code,stock_uom
|
||||
""" , (fg_qty, bom_no))
|
||||
self.make_items_dict(fl_bom_sa_child_item)
|
||||
|
||||
# Update only qty remaining to be issued for production
|
||||
if self.doc.process == 'Material Transfer':
|
||||
self.update_only_remaining_qty()
|
||||
|
||||
|
||||
|
||||
def add_to_stock_entry_detail(self, source_wh, target_wh, item_dict, fg_item = 0, bom_no = ''):
|
||||
for d in item_dict:
|
||||
se_child = addchild(self.doc, 'mtn_details', 'Stock Entry Detail', 0, self.doclist)
|
||||
se_child.s_warehouse = source_wh
|
||||
se_child.t_warehouse = target_wh
|
||||
se_child.fg_item = fg_item
|
||||
se_child.item_code = cstr(d)
|
||||
se_child.description = item_dict[d][1]
|
||||
se_child.uom = item_dict[d][2]
|
||||
se_child.stock_uom = item_dict[d][2]
|
||||
se_child.reqd_qty = flt(item_dict[d][0])
|
||||
se_child.qty = flt(item_dict[d][0])
|
||||
se_child.transfer_qty = flt(item_dict[d][0])
|
||||
se_child.conversion_factor = 1.00
|
||||
if fg_item: se_child.bom_no = bom_no
|
||||
|
||||
def validate_bom_no(self):
|
||||
if self.doc.bom_no:
|
||||
if not self.doc.fg_completed_qty:
|
||||
msgprint("Please enter FG Completed Qty", raise_exception=1)
|
||||
if not self.doc.consider_sa_items_as_raw_materials:
|
||||
msgprint("Please confirm whether you want to consider sub assembly item as raw materials", raise_exception=1)
|
||||
|
||||
|
||||
# get items
|
||||
#------------------
|
||||
def get_items(self):
|
||||
if self.doc.purpose == 'Production Order':
|
||||
pro_obj = self.doc.production_order and get_obj('Production Order', self.doc.production_order) or ''
|
||||
self.validate_for_production_order(pro_obj)
|
||||
|
||||
bom_no = pro_obj.doc.bom_no
|
||||
fg_qty = (self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty)
|
||||
consider_sa_items_as_rm = pro_obj.doc.consider_sa_items
|
||||
elif self.doc.purpose == 'Other':
|
||||
self.validate_bom_no()
|
||||
bom_no = self.doc.bom_no
|
||||
fg_qty = self.doc.fg_completed_qty
|
||||
consider_sa_items_as_rm = self.doc.consider_sa_items_as_raw_materials
|
||||
|
||||
self.get_raw_materials(bom_no, fg_qty, consider_sa_items_as_rm)
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'mtn_details', 1)
|
||||
|
||||
sw = (self.doc.process == 'Backflush') and cstr(pro_obj.doc.wip_warehouse) or ''
|
||||
tw = (self.doc.process == 'Material Transfer') and cstr(pro_obj.doc.wip_warehouse) or ''
|
||||
self.add_to_stock_entry_detail(sw, tw, self.item_dict)
|
||||
|
||||
fg_item_dict = {}
|
||||
if self.doc.process == 'Backflush':
|
||||
sw = ''
|
||||
tw = cstr(pro_obj.doc.fg_warehouse)
|
||||
fg_item_dict = {cstr(pro_obj.doc.production_item) : [self.doc.fg_completed_qty, pro_obj.doc.description, pro_obj.doc.stock_uom]}
|
||||
elif self.doc.purpose == 'Other' and self.doc.bom_no:
|
||||
sw, tw = '', ''
|
||||
item = sql("select item, description, uom from `tabBOM` where name = %s", self.doc.bom_no, as_dict=1)
|
||||
fg_item_dict = {item[0]['item'] : [self.doc.fg_completed_qty, item[0]['description'], item[0]['uom']]}
|
||||
|
||||
if fg_item_dict:
|
||||
self.add_to_stock_entry_detail(sw, tw, fg_item_dict, fg_item = 1, bom_no = bom_no)
|
||||
|
||||
|
||||
|
||||
def validate_transfer_qty(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if flt(d.transfer_qty) <= 0:
|
||||
msgprint("Transfer Quantity can not be less than or equal to zero at Row No " + cstr(d.idx))
|
||||
raise Exception
|
||||
|
||||
|
||||
def calc_amount(self):
|
||||
total_amount = 0
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
|
||||
total_amount += flt(d.amount)
|
||||
self.doc.total_amount = flt(total_amount)
|
||||
|
||||
|
||||
def add_to_values(self, d, wh, qty, is_cancelled):
|
||||
self.values.append({
|
||||
'item_code' : d.item_code,
|
||||
'warehouse' : wh,
|
||||
'transaction_date' : self.doc.transfer_date,
|
||||
'posting_date' : self.doc.posting_date,
|
||||
'posting_time' : self.doc.posting_time,
|
||||
'voucher_type' : 'Stock Entry',
|
||||
'voucher_no' : self.doc.name,
|
||||
'voucher_detail_no' : d.name,
|
||||
'actual_qty' : qty,
|
||||
'incoming_rate' : flt(d.incoming_rate) or 0,
|
||||
'stock_uom' : d.stock_uom,
|
||||
'company' : self.doc.company,
|
||||
'fiscal_year' : self.doc.fiscal_year,
|
||||
'is_cancelled' : (is_cancelled ==1) and 'Yes' or 'No',
|
||||
'batch_no' : d.batch_no,
|
||||
'serial_no' : d.serial_no
|
||||
})
|
||||
|
||||
|
||||
def update_stock_ledger(self, is_cancelled=0):
|
||||
self.values = []
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if cstr(d.s_warehouse):
|
||||
self.add_to_values(d, cstr(d.s_warehouse), -flt(d.transfer_qty), is_cancelled)
|
||||
if cstr(d.t_warehouse):
|
||||
self.add_to_values(d, cstr(d.t_warehouse), flt(d.transfer_qty), is_cancelled)
|
||||
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, self.doc.amended_from and 'Yes' or 'No')
|
||||
|
||||
|
||||
def validate_for_production_order(self, pro_obj):
|
||||
if self.doc.purpose == 'Production Order' or self.doc.process or self.doc.production_order:
|
||||
if self.doc.purpose != 'Production Order':
|
||||
msgprint("Purpose should be 'Production Order'.")
|
||||
raise Exception
|
||||
if not self.doc.process:
|
||||
msgprint("Process Field is mandatory.")
|
||||
raise Exception
|
||||
if self.doc.process == 'Backflush' and not flt(self.doc.fg_completed_qty):
|
||||
msgprint("FG Completed Qty is mandatory as the process selected is 'Backflush'")
|
||||
raise Exception
|
||||
if self.doc.process == 'Material Transfer' and flt(self.doc.fg_completed_qty):
|
||||
msgprint("FG Completed Qty should be zero. As the Process selected is 'Material Transfer'.")
|
||||
raise Exception
|
||||
if not self.doc.production_order:
|
||||
msgprint("Production Order field is mandatory")
|
||||
raise Exception
|
||||
if flt(pro_obj.doc.qty) < flt(pro_obj.doc.produced_qty) + flt(self.doc.fg_completed_qty) :
|
||||
msgprint("error:Already Produced Qty for %s is %s and maximum allowed Qty is %s" % (pro_obj.doc.production_item, cstr(pro_obj.doc.produced_qty) or 0.00 , cstr(pro_obj.doc.qty)))
|
||||
raise Exception
|
||||
|
||||
|
||||
def validate(self):
|
||||
sl_obj = get_obj("Stock Ledger", "Stock Ledger")
|
||||
sl_obj.scrub_serial_nos(self)
|
||||
sl_obj.validate_serial_no(self, 'mtn_details')
|
||||
pro_obj = ''
|
||||
if self.doc.production_order:
|
||||
pro_obj = get_obj('Production Order', self.doc.production_order)
|
||||
self.validate_for_production_order(pro_obj)
|
||||
self.get_stock_and_rate(pro_obj and pro_obj.doc.bom_no or '')
|
||||
self.validate_warehouse(pro_obj)
|
||||
self.validate_incoming_rate()
|
||||
self.validate_bom_belongs_to_item()
|
||||
self.calc_amount()
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
|
||||
|
||||
|
||||
# If target warehouse exists, incoming rate is mandatory
|
||||
# --------------------------------------------------------
|
||||
def validate_incoming_rate(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if not flt(d.incoming_rate) and d.t_warehouse:
|
||||
msgprint("Rate is mandatory for Item: %s at row %s" % (d.item_code, d.idx), raise_exception=1)
|
||||
|
||||
|
||||
def validate_bom_belongs_to_item(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if d.bom_no and not webnotes.conn.sql("""\
|
||||
SELECT name FROM `tabBOM`
|
||||
WHERE item = %s and name = %s
|
||||
""", (d.item_code, d.bom_no)):
|
||||
msgprint("BOM %s does not belong to Item: %s at row %s" % (d.bom_no, d.item_code, d.idx), raise_exception=1)
|
||||
|
||||
|
||||
# Validate warehouse
|
||||
# -----------------------------------
|
||||
def validate_warehouse(self, pro_obj):
|
||||
fg_qty = 0
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if not d.s_warehouse and not d.t_warehouse:
|
||||
d.s_warehouse = self.doc.from_warehouse
|
||||
d.t_warehouse = self.doc.to_warehouse
|
||||
|
||||
if not (d.s_warehouse or d.t_warehouse):
|
||||
msgprint("Atleast one warehouse is mandatory for Stock Entry ")
|
||||
raise Exception
|
||||
if d.s_warehouse and not sql("select name from tabWarehouse where name = '%s'" % d.s_warehouse):
|
||||
msgprint("Invalid Warehouse: %s" % self.doc.s_warehouse)
|
||||
raise Exception
|
||||
if d.t_warehouse and not sql("select name from tabWarehouse where name = '%s'" % d.t_warehouse):
|
||||
msgprint("Invalid Warehouse: %s" % self.doc.t_warehouse)
|
||||
raise Exception
|
||||
if d.s_warehouse == d.t_warehouse:
|
||||
msgprint("Source and Target Warehouse Cannot be Same.")
|
||||
raise Exception
|
||||
if self.doc.purpose == 'Material Issue':
|
||||
if not cstr(d.s_warehouse):
|
||||
msgprint("Source Warehouse is Mandatory for Purpose => 'Material Issue'")
|
||||
raise Exception
|
||||
if cstr(d.t_warehouse):
|
||||
msgprint("Target Warehouse is not Required for Purpose => 'Material Issue'")
|
||||
raise Exception
|
||||
if self.doc.purpose == 'Material Transfer':
|
||||
if not cstr(d.s_warehouse) or not cstr(d.t_warehouse):
|
||||
msgprint("Source Warehouse and Target Warehouse both are Mandatory for Purpose => 'Material Transfer'")
|
||||
raise Exception
|
||||
if self.doc.purpose == 'Material Receipt':
|
||||
if not cstr(d.t_warehouse):
|
||||
msgprint("Target Warehouse is Mandatory for Purpose => 'Material Receipt'")
|
||||
raise Exception
|
||||
if cstr(d.s_warehouse):
|
||||
msgprint("Source Warehouse is not Required for Purpose => 'Material Receipt'")
|
||||
raise Exception
|
||||
if self.doc.process == 'Material Transfer':
|
||||
if cstr(d.t_warehouse) != (pro_obj.doc.wip_warehouse):
|
||||
msgprint(" Target Warehouse should be same as WIP Warehouse %s in Production Order %s at Row No %s" % (cstr(pro_obj.doc.wip_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)) )
|
||||
raise Exception
|
||||
if not cstr(d.s_warehouse):
|
||||
msgprint("Please Enter Source Warehouse at Row No %s." % (cstr(d.idx)))
|
||||
raise Exception
|
||||
if self.doc.process == 'Backflush':
|
||||
if flt(d.fg_item):
|
||||
if cstr(pro_obj.doc.production_item) != cstr(d.item_code):
|
||||
msgprint("Item %s in Stock Entry Detail as Row No %s do not match with Item %s in Production Order %s" % (cstr(d.item_code), cstr(d.idx), cstr(pro_obj.doc.production_item), cstr(pro_obj.doc.name)))
|
||||
raise Exception
|
||||
if cstr(d.t_warehouse) != cstr(pro_obj.doc.fg_warehouse):
|
||||
msgprint("As Item %s is FG Item. Target Warehouse should be same as FG Warehouse %s in Production Order %s, at Row No %s. " % ( cstr(d.item_code), cstr(pro_obj.doc.fg_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)))
|
||||
raise Exception
|
||||
if cstr(d.s_warehouse):
|
||||
msgprint("As Item %s is a FG Item. There should be no Source Warehouse at Row No %s" % (cstr(d.item_code), cstr(d.idx)))
|
||||
raise Exception
|
||||
if not flt(d.fg_item):
|
||||
if cstr(d.t_warehouse):
|
||||
msgprint("As Item %s is not a FG Item. There should no Tareget Warehouse at Row No %s" % (cstr(d.item_code), cstr(d.idx)))
|
||||
raise Exception
|
||||
if cstr(d.s_warehouse) != cstr(pro_obj.doc.wip_warehouse):
|
||||
msgprint("As Item %s is Raw Material. Source Warehouse should be same as WIP Warehouse %s in Production Order %s, at Row No %s. " % ( cstr(d.item_code), cstr(pro_obj.doc.wip_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)))
|
||||
raise Exception
|
||||
if d.fg_item and (self.doc.purpose == 'Other' or self.doc.process == 'Backflush'):
|
||||
fg_qty = flt(fg_qty) + flt(d.transfer_qty)
|
||||
|
||||
d.save()
|
||||
if self.doc.fg_completed_qty and flt(self.doc.fg_completed_qty) != flt(fg_qty):
|
||||
msgprint("The Total of FG Qty %s in Stock Entry Detail do not match with FG Completed Qty %s" % (flt(fg_qty), flt(self.doc.fg_completed_qty)))
|
||||
raise Exception
|
||||
|
||||
|
||||
def update_production_order(self, is_submit):
|
||||
if self.doc.production_order:
|
||||
pro_obj = get_obj("Production Order", self.doc.production_order)
|
||||
if flt(pro_obj.doc.docstatus) != 1:
|
||||
msgprint("You cannot do any transaction against Production Order : %s, as it's not submitted" % (pro_obj.doc.name))
|
||||
raise Exception
|
||||
if pro_obj.doc.status == 'Stopped':
|
||||
msgprint("You cannot do any transaction against Production Order : %s, as it's status is 'Stopped'" % (pro_obj.doc.name))
|
||||
raise Exception
|
||||
if getdate(pro_obj.doc.posting_date) > getdate(self.doc.posting_date):
|
||||
msgprint("Posting Date of Stock Entry cannot be before Posting Date of Production Order "+ cstr(self.doc.production_order))
|
||||
raise Exception
|
||||
if self.doc.process == 'Backflush':
|
||||
pro_obj.doc.produced_qty = flt(pro_obj.doc.produced_qty) + (is_submit and 1 or -1 ) * flt(self.doc.fg_completed_qty)
|
||||
get_obj('Warehouse', pro_obj.doc.fg_warehouse).update_bin(0, 0, 0, 0, (is_submit and 1 or -1 ) * flt(self.doc.fg_completed_qty), pro_obj.doc.production_item, now())
|
||||
pro_obj.doc.status = (flt(pro_obj.doc.qty) == flt(pro_obj.doc.produced_qty)) and 'Completed' or 'In Process'
|
||||
pro_obj.doc.save()
|
||||
|
||||
|
||||
# Create / Update Serial No
|
||||
# ----------------------------------
|
||||
def update_serial_no(self, is_submit):
|
||||
sl_obj = get_obj('Stock Ledger')
|
||||
if is_submit:
|
||||
sl_obj.validate_serial_no_warehouse(self, 'mtn_details')
|
||||
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if d.serial_no:
|
||||
serial_nos = sl_obj.get_sr_no_list(d.serial_no)
|
||||
for x in serial_nos:
|
||||
serial_no = x.strip()
|
||||
if d.s_warehouse:
|
||||
sl_obj.update_serial_delivery_details(self, d, serial_no, is_submit)
|
||||
if d.t_warehouse:
|
||||
sl_obj.update_serial_purchase_details(self, d, serial_no, is_submit, self.doc.purpose)
|
||||
|
||||
if self.doc.purpose == 'Purchase Return':
|
||||
#delete_doc("Serial No", serial_no)
|
||||
serial_doc = Document("Serial No", serial_no)
|
||||
serial_doc.status = is_submit and 'Purchase Returned' or 'In Store'
|
||||
serial_doc.docstatus = is_submit and 2 or 0
|
||||
serial_doc.save()
|
||||
|
||||
|
||||
def on_submit(self):
|
||||
self.validate_transfer_qty()
|
||||
# Check for Approving Authority
|
||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.total_amount)
|
||||
self.update_serial_no(1)
|
||||
self.update_stock_ledger(0)
|
||||
# update Production Order
|
||||
self.update_production_order(1)
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
self.update_serial_no(0)
|
||||
self.update_stock_ledger(1)
|
||||
# update Production Order
|
||||
self.update_production_order(0)
|
||||
|
||||
|
||||
def get_cust_values(self):
|
||||
tbl = self.doc.delivery_note_no and 'Delivery Note' or 'Sales Invoice'
|
||||
record_name = self.doc.delivery_note_no or self.doc.sales_invoice_no
|
||||
res = sql("select customer,customer_name, customer_address from `tab%s` where name = '%s'" % (tbl, record_name))
|
||||
ret = {
|
||||
'customer' : res and res[0][0] or '',
|
||||
'customer_name' : res and res[0][1] or '',
|
||||
'customer_address' : res and res[0][2] or ''}
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def get_cust_addr(self):
|
||||
res = sql("select customer_name from `tabCustomer` where name = '%s'"%self.doc.customer)
|
||||
addr = self.get_address_text(customer = self.doc.customer)
|
||||
ret = {
|
||||
'customer_name' : res and res[0][0] or '',
|
||||
'customer_address' : addr and addr[0] or ''}
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
def get_supp_values(self):
|
||||
res = sql("select supplier,supplier_name,supplier_address from `tabPurchase Receipt` where name = '%s'"%self.doc.purchase_receipt_no)
|
||||
ret = {
|
||||
'supplier' : res and res[0][0] or '',
|
||||
'supplier_name' :res and res[0][1] or '',
|
||||
'supplier_address' : res and res[0][2] or ''}
|
||||
return ret
|
||||
|
||||
|
||||
def get_supp_addr(self):
|
||||
res = sql("select supplier_name,address from `tabSupplier` where name = '%s'"%self.doc.supplier)
|
||||
addr = self.get_address_text(supplier = self.doc.supplier)
|
||||
ret = {
|
||||
'supplier_name' : res and res[0][0] or '',
|
||||
'supplier_address' : addr and addr[0] or ''}
|
||||
return ret
|
||||
991
stock/doctype/stock_entry/stock_entry.txt
Normal file
991
stock/doctype/stock_entry/stock_entry.txt
Normal file
@@ -0,0 +1,991 @@
|
||||
# DocType, Stock Entry
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-03 11:12:49',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-17 13:32:44',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1334303911',
|
||||
'allow_attach': 0,
|
||||
'allow_copy': 0,
|
||||
'allow_email': 0,
|
||||
'allow_print': 0,
|
||||
'allow_rename': 0,
|
||||
'allow_trash': 0,
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'hide_heading': 0,
|
||||
'hide_toolbar': 0,
|
||||
'in_create': 0,
|
||||
'in_dialog': 0,
|
||||
'is_submittable': 1,
|
||||
'is_transaction_doc': 0,
|
||||
'issingle': 0,
|
||||
'max_attachments': 0,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'print_outline': u'No',
|
||||
'read_only': 0,
|
||||
'read_only_onload': 0,
|
||||
'search_fields': u'transfer_date, from_warehouse, to_warehouse, purpose, remarks',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'%(remarks)s',
|
||||
'tag_fields': u'purpose',
|
||||
'use_template': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Stock Entry',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Stock Entry',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Stock Entry
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Stock Entry'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Production User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Production User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'Production User',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Production Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Production Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'Production Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'col1',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'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',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Series',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'naming_series',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nSTE',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purpose',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Purpose',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'purpose',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'Material Issue\nMaterial Receipt\nMaterial Transfer\nSales Return\nPurchase Return\nSubcontracting\nProduction Order\nOther',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_note_no',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Delivery Note No',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'delivery_note_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Delivery Note',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'purchase_receipt_no',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Purchase Receipt No',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'purchase_receipt_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Purchase Receipt',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'sales_invoice_no',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Sales Invoice No',
|
||||
'options': u'Sales Invoice',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'process',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Process',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'process',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nMaterial Transfer\nBackflush',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'production_order',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Production Order',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'production_order',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Production Order',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': u"eval:doc.purpose == 'Other'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'bom_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'BOM No',
|
||||
'options': u'BOM',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.purpose == 'Other'",
|
||||
'description': u'Select "Yes" if stock is maintained and tracked for sub-assembly items. Select "No" if you want child items of sub-assembly for material transfer.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'consider_sa_items_as_raw_materials',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Consider SA Items as Raw Materials',
|
||||
'options': u'\nNo\nYes',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fg_completed_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'FG Completed Qty',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'fg_completed_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'get_items',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Get Items',
|
||||
'no_copy': 0,
|
||||
'oldfieldtype': u'Button',
|
||||
'options': u'get_items',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Warehouse HTML',
|
||||
'no_copy': 0,
|
||||
'oldfieldtype': u'HTML',
|
||||
'options': u"<div class='columnHeading'>Warehouse</div>",
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'from_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Source Warehouse',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'from_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<b>Notes:</b> Either Source or Target is Mandatory',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'to_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Target Warehouse',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'to_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'col2',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'description': u'The date at which current entry will get or has actually executed.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'posting_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Posting Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'posting_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'posting_time',
|
||||
'fieldtype': u'Time',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Posting Time',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'posting_time',
|
||||
'oldfieldtype': u'Time',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'remarks',
|
||||
'fieldtype': u'Text',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Remarks',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'remarks',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'items_section',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Items',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'mtn_details',
|
||||
'fieldtype': u'Table',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'MTN Details',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'mtn_details',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Stock Entry Detail',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_section',
|
||||
'fieldtype': u'Section Break',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'options': u'Simple',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'total_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Total Amount',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'total_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'col3',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'get_stock_and_rate',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Get Stock and Rate',
|
||||
'oldfieldtype': u'Button',
|
||||
'options': u'get_stock_and_rate',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_section',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Contact Info',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Supplier',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'supplier',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Supplier',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Supplier Name',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'supplier_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier_address',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Supplier Address',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'supplier_address',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Customer',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Customer Name',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'customer_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Customer Address',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'customer_address',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'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'col4',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'project_name',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Project Name',
|
||||
'oldfieldname': u'project_name',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Project',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'select_print_heading',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Select Print Heading',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'select_print_heading',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Print Heading',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'cancel_reason',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Cancel Reason',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'cancel_reason',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'default': u'Today',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transfer_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Transfer Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'transfer_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'col5',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'is_excisable_goods',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Is Excisable Goods',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'is_excisable_goods',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nYes\nNo',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'excisable_goods',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Excisable Goods',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'excisable_goods',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nReturnable\nNon-Returnable',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'under_rule',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Under Rule',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'under_rule',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nOrdinary\n57 AC (5) a\n57 F (2) Non-Exc.',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transporter',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Transporter',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'transporter',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Fiscal Year',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amended_from',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Amended From',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amended_from',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Stock Entry',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'description': u'The date at which current entry is corrected in the system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amendment_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Amendment Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amendment_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
}
|
||||
]
|
||||
24
stock/doctype/stock_entry/stock_entry_list.js
Normal file
24
stock/doctype/stock_entry/stock_entry_list.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// render
|
||||
wn.doclistviews['Stock Entry'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d);
|
||||
this.fields = this.fields.concat([
|
||||
"`tabStock Entry`.purpose",
|
||||
"`tabStock Entry`.from_warehouse",
|
||||
"`tabStock Entry`.to_warehouse",
|
||||
"`tabStock Entry`.posting_date",
|
||||
]);
|
||||
},
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '3%', content:'docstatus'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '15%', content:'purpose+tags', css: {color:'#222'}},
|
||||
{width: '18%', content:'from_warehouse', template: 'From %(from_warehouse)s'},
|
||||
{width: '18%', content:'to_warehouse', template: 'To %(to_warehouse)s'},
|
||||
{width: '12%', content:'posting_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Stock Entry Date", type: "date"}
|
||||
]
|
||||
});
|
||||
1
stock/doctype/stock_entry_detail/__init__.py
Normal file
1
stock/doctype/stock_entry_detail/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
266
stock/doctype/stock_entry_detail/stock_entry_detail.txt
Normal file
266
stock/doctype/stock_entry_detail/stock_entry_detail.txt
Normal file
@@ -0,0 +1,266 @@
|
||||
# DocType, Stock Entry Detail
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-04-13 11:56:38',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-01 16:16:20',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'MTND/.######',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Stock',
|
||||
'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'Stock Entry Detail',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Stock Entry Detail
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Stock Entry Detail'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u's_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Source Warehouse',
|
||||
'oldfieldname': u's_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u't_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Target Warehouse',
|
||||
'oldfieldname': u't_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# 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'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'uom',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'UOM',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'incoming_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Incoming Rate',
|
||||
'oldfieldname': u'incoming_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount',
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Serial No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'serial_no',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'batch_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Batch No',
|
||||
'oldfieldname': u'batch_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Batch',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'reqd_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Reqd Qty',
|
||||
'oldfieldname': u'reqd_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 3,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'actual_qty',
|
||||
'fieldtype': u'Read Only',
|
||||
'in_filter': 1,
|
||||
'label': u'Actual Qty (at source)',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'actual_qty',
|
||||
'oldfieldtype': u'Read Only',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'conversion_factor',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Conversion Factor',
|
||||
'oldfieldname': u'conversion_factor',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transfer_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Stock Qty',
|
||||
'oldfieldname': u'transfer_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 0,
|
||||
'label': u'Stock UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'UOM',
|
||||
'permlevel': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'description': u'BOM No. for a Finished Good Item',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'bom_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'BOM No.',
|
||||
'options': u'BOM',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fg_item',
|
||||
'fieldtype': u'Check',
|
||||
'in_filter': 1,
|
||||
'label': u'FG Item',
|
||||
'oldfieldname': u'fg_item',
|
||||
'oldfieldtype': u'Check',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
}
|
||||
]
|
||||
1
stock/doctype/stock_ledger/__init__.py
Normal file
1
stock/doctype/stock_ledger/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
256
stock/doctype/stock_ledger/stock_ledger.py
Normal file
256
stock/doctype/stock_ledger/stock_ledger.py
Normal file
@@ -0,0 +1,256 @@
|
||||
# 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
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
def get_sr_no_list(sr_nos, qty = 0, item_code = ''):
|
||||
serial_nos = cstr(sr_nos).strip().replace(',', '\n').split('\n')
|
||||
valid_serial_nos = []
|
||||
for val in serial_nos:
|
||||
if val:
|
||||
if val in valid_serial_nos:
|
||||
msgprint("You have entered duplicate serial no: %s" % val, raise_exception=1)
|
||||
else:
|
||||
valid_serial_nos.append(val.strip())
|
||||
if qty and cstr(sr_nos).strip() and len(valid_serial_nos) != abs(qty):
|
||||
msgprint("Please enter serial nos for "+ cstr(abs(qty)) + " quantity against item code: " + item_code , raise_exception = 1)
|
||||
return valid_serial_nos
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
|
||||
def scrub_serial_nos(self, obj, table_name = ''):
|
||||
if not table_name:
|
||||
table_name = obj.fname
|
||||
|
||||
for d in getlist(obj.doclist, table_name):
|
||||
if d.serial_no:
|
||||
d.serial_no = d.serial_no.replace(',', '\n')
|
||||
d.save()
|
||||
|
||||
|
||||
def validate_serial_no_warehouse(self, obj, fname):
|
||||
for d in getlist(obj.doclist, fname):
|
||||
wh = d.warehouse or d.s_warehouse
|
||||
if d.serial_no and wh:
|
||||
serial_nos = self.get_sr_no_list(d.serial_no)
|
||||
for s in serial_nos:
|
||||
s = s.strip()
|
||||
sr_war = sql("select warehouse,name from `tabSerial No` where name = '%s'" % (s))
|
||||
if not sr_war:
|
||||
msgprint("Serial No %s does not exists"%s, raise_exception = 1)
|
||||
elif not sr_war[0][0]:
|
||||
msgprint("Warehouse not mentioned in the Serial No <b>%s</b>" % s, raise_exception = 1)
|
||||
elif sr_war[0][0] != wh:
|
||||
msgprint("Serial No : %s for Item : %s doesn't exists in Warehouse : %s" % (s, d.item_code, wh), raise_exception = 1)
|
||||
|
||||
|
||||
def validate_serial_no(self, obj, fname):
|
||||
"""check whether serial no is required"""
|
||||
for d in getlist(obj.doclist, fname):
|
||||
is_stock_item = get_value('Item', d.item_code, 'is_stock_item')
|
||||
ar_required = get_value('Item', d.item_code, 'has_serial_no')
|
||||
|
||||
# [bug fix] need to strip serial nos of all spaces and new lines for validation
|
||||
serial_no = cstr(d.serial_no).strip()
|
||||
|
||||
if serial_no:
|
||||
if is_stock_item != 'Yes':
|
||||
msgprint("Serial No is not required for non-stock item: %s" % d.item_code, raise_exception=1)
|
||||
elif ar_required != 'Yes':
|
||||
msgprint("If serial no required, please select 'Yes' in 'Has Serial No' in Item :" + d.item_code + \
|
||||
', otherwise please remove serial no', raise_exception=1)
|
||||
elif ar_required == 'Yes' and not serial_no:
|
||||
msgprint("Serial no is mandatory for item: "+ d.item_code, raise_exception = 1)
|
||||
|
||||
# validate rejected serial nos
|
||||
if fname == 'purchase_receipt_details' and flt(d.rejected_qty) > 0 and ar_required == 'Yes' and not d.rejected_serial_no:
|
||||
msgprint("Rejected serial no is mandatory for rejected qty of item: "+ d.item_code, raise_exception = 1)
|
||||
|
||||
|
||||
def get_sr_no_list(self, sr_nos, qty = 0, item_code = ''):
|
||||
return get_sr_no_list(sr_nos, qty, item_code)
|
||||
|
||||
|
||||
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec):
|
||||
item_details = sql("select item_group, warranty_period from `tabItem` where name = '%s' and \
|
||||
(ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) " %(d.item_code), as_dict=1)
|
||||
|
||||
s.purchase_document_type = obj.doc.doctype
|
||||
s.purchase_document_no = obj.doc.name
|
||||
s.purchase_date = obj.doc.posting_date
|
||||
s.purchase_time = obj.doc.posting_time
|
||||
s.purchase_rate = d.valuation_rate or d.incoming_rate
|
||||
s.item_code = d.item_code
|
||||
s.item_name = d.item_name
|
||||
s.brand = d.brand
|
||||
s.description = d.description
|
||||
s.item_group = item_details and item_details[0]['item_group'] or ''
|
||||
s.warranty_period = item_details and item_details[0]['warranty_period'] or 0
|
||||
s.supplier = obj.doc.supplier
|
||||
s.supplier_name = obj.doc.supplier_name
|
||||
s.address_display = obj.doc.address_display or obj.doc.supplier_address
|
||||
s.warehouse = d.warehouse or d.t_warehouse
|
||||
s.docstatus = 0
|
||||
s.status = 'In Store'
|
||||
s.modified = nowdate()
|
||||
s.modified_by = session['user']
|
||||
s.serial_no = serial_no
|
||||
s.sle_exists = 1
|
||||
s.fiscal_year = obj.doc.fiscal_year
|
||||
s.company = obj.doc.company
|
||||
s.save(new_rec)
|
||||
|
||||
|
||||
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = ''):
|
||||
exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
|
||||
if is_submit:
|
||||
if exists and exists[0][2] != 2 and purpose not in ['Material Transfer', 'Sales Return']:
|
||||
msgprint("Serial No: %s already %s" % (serial_no, exists and exists[0][1]), raise_exception = 1)
|
||||
elif exists:
|
||||
s = Document('Serial No', exists and exists[0][0])
|
||||
self.set_pur_serial_no_values(obj, serial_no, d, s, new_rec = 0)
|
||||
else:
|
||||
s = Document('Serial No')
|
||||
self.set_pur_serial_no_values(obj, serial_no, d, s, new_rec = 1)
|
||||
else:
|
||||
if exists and exists[0][1] == 'Delivered' and exists[0][2] != 2:
|
||||
msgprint("Serial No: %s is already delivered, you can not cancel the document." % serial_no, raise_exception=1)
|
||||
elif purpose == 'Material Transfer':
|
||||
sql("update `tabSerial No` set status = 'In Store', purchase_document_type = '', purchase_document_no = '', warehouse = '%s' where name = '%s'" % (d.s_warehouse, serial_no))
|
||||
elif purpose == 'Sales Return':
|
||||
sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
|
||||
else:
|
||||
sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
|
||||
|
||||
|
||||
def check_serial_no_exists(self, serial_no, item_code):
|
||||
chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
|
||||
if not chk:
|
||||
msgprint("Serial No: %s does not exists in the system" % serial_no, raise_exception=1)
|
||||
elif chk and chk[0]['item_code'] != item_code:
|
||||
msgprint("Serial No: %s not belong to item: %s" % (serial_no, item_code), raise_exception=1)
|
||||
elif chk and chk[0]['docstatus'] == 2:
|
||||
msgprint("Serial No: %s of Item : %s is trashed in the system" % (serial_no, item_code), raise_exception = 1)
|
||||
elif chk and chk[0]['status'] == 'Delivered':
|
||||
msgprint("Serial No: %s of Item : %s is already delivered." % (serial_no, item_code), raise_exception = 1)
|
||||
|
||||
|
||||
def set_delivery_serial_no_values(self, obj, serial_no):
|
||||
s = Document('Serial No', serial_no)
|
||||
s.delivery_document_type = obj.doc.doctype
|
||||
s.delivery_document_no = obj.doc.name
|
||||
s.delivery_date = obj.doc.posting_date
|
||||
s.delivery_time = obj.doc.posting_time
|
||||
s.customer = obj.doc.customer
|
||||
s.customer_name = obj.doc.customer_name
|
||||
s.delivery_address = obj.doc.address_display
|
||||
s.territory = obj.doc.territory
|
||||
s.warranty_expiry_date = s.warranty_period and add_days(cstr(obj.doc.posting_date), s.warranty_period) or ''
|
||||
s.docstatus = 1
|
||||
s.status = 'Delivered'
|
||||
s.modified = nowdate()
|
||||
s.modified_by = session['user']
|
||||
s.save()
|
||||
|
||||
|
||||
def update_serial_delivery_details(self, obj, d, serial_no, is_submit):
|
||||
if is_submit:
|
||||
self.check_serial_no_exists(serial_no, d.item_code)
|
||||
self.set_delivery_serial_no_values(obj, serial_no)
|
||||
else:
|
||||
sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
|
||||
|
||||
|
||||
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
|
||||
import datetime
|
||||
for d in getlist(obj.doclist, fname):
|
||||
if d.serial_no:
|
||||
serial_nos = self.get_sr_no_list(d.serial_no)
|
||||
for a in serial_nos:
|
||||
serial_no = a.strip()
|
||||
if is_incoming:
|
||||
self.update_serial_purchase_details(obj, d, serial_no, is_submit)
|
||||
else:
|
||||
self.update_serial_delivery_details(obj, d, serial_no, is_submit)
|
||||
|
||||
if fname == 'purchase_receipt_details' and d.rejected_qty and d.rejected_serial_no:
|
||||
serial_nos = self.get_sr_no_list(d.rejected_serial_no)
|
||||
for a in serial_nos:
|
||||
self.update_serial_purchase_details(obj, d, a, is_submit)
|
||||
|
||||
|
||||
def update_stock(self, values, is_amended = 'No'):
|
||||
for v in values:
|
||||
sle_id, serial_nos = '', ''
|
||||
# get serial nos
|
||||
if v["serial_no"]:
|
||||
serial_nos = self.get_sr_no_list(v["serial_no"], v['actual_qty'], v['item_code'])
|
||||
|
||||
# reverse quantities for cancel
|
||||
if v['is_cancelled'] == 'Yes':
|
||||
v['actual_qty'] = -flt(v['actual_qty'])
|
||||
# cancel matching entry
|
||||
sql("update `tabStock Ledger Entry` set is_cancelled='Yes' where voucher_no=%s \
|
||||
and voucher_type=%s", (v['voucher_no'], v['voucher_type']))
|
||||
|
||||
if v["actual_qty"]:
|
||||
sle_id = self.make_entry(v)
|
||||
|
||||
get_obj('Warehouse', v["warehouse"]).update_bin(flt(v["actual_qty"]), 0, 0, 0, 0, v["item_code"], \
|
||||
v["posting_date"], sle_id, v["posting_time"], '', v["is_cancelled"],v["voucher_type"],v["voucher_no"], is_amended)
|
||||
|
||||
|
||||
def make_entry(self, args):
|
||||
sle = Document(doctype = 'Stock Ledger Entry')
|
||||
for k in args.keys():
|
||||
# adds warehouse_type
|
||||
if k == 'warehouse':
|
||||
sle.fields['warehouse_type'] = get_value('Warehouse' , args[k], 'warehouse_type')
|
||||
sle.fields[k] = args[k]
|
||||
sle_obj = get_obj(doc=sle)
|
||||
|
||||
# validate
|
||||
sle_obj.validate()
|
||||
sle.save(new = 1)
|
||||
return sle.name
|
||||
|
||||
def repost(self):
|
||||
"""
|
||||
Repost everything!
|
||||
"""
|
||||
for wh in sql("select name from tabWarehouse"):
|
||||
get_obj('Warehouse', wh[0]).repost_stock()
|
||||
57
stock/doctype/stock_ledger/stock_ledger.txt
Normal file
57
stock/doctype/stock_ledger/stock_ledger.txt
Normal file
@@ -0,0 +1,57 @@
|
||||
# DocType, Stock Ledger
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:38',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:38',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'hide_toolbar': 1,
|
||||
'in_create': 1,
|
||||
'issingle': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'read_only': 1,
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 10
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Stock Ledger',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 1,
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Stock Ledger
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Stock Ledger'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Material User'
|
||||
}
|
||||
]
|
||||
1
stock/doctype/stock_ledger_entry/__init__.py
Normal file
1
stock/doctype/stock_ledger_entry/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
116
stock/doctype/stock_ledger_entry/stock_ledger_entry.py
Normal file
116
stock/doctype/stock_ledger_entry/stock_ledger_entry.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# 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, cint, flt, cstr, getdate
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
msgprint = webnotes.msgprint
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
#check for item quantity available in stock
|
||||
def actual_amt_check(self):
|
||||
if self.doc.batch_no:
|
||||
batch_bal = flt(sql("select sum(actual_qty) from `tabStock Ledger Entry` where warehouse = '%s' and item_code = '%s' and batch_no = '%s'"%(self.doc.warehouse,self.doc.item_code,self.doc.batch_no))[0][0])
|
||||
self.doc.fields.update({'batch_bal': batch_bal})
|
||||
|
||||
if (batch_bal + self.doc.actual_qty) < 0:
|
||||
msgprint("""Not enough quantity (requested: %(actual_qty)s, current: %(batch_bal)s in Batch
|
||||
<b>%(batch_no)s</b> for Item <b>%(item_code)s</b> at Warehouse<b>%(warehouse)s</b>
|
||||
as on %(posting_date)s %(posting_time)s""" % self.doc.fields, raise_exception = 1)
|
||||
|
||||
self.doc.fields.pop('batch_bal')
|
||||
|
||||
|
||||
# mandatory
|
||||
# ---------
|
||||
|
||||
def validate_mandatory(self):
|
||||
mandatory = ['warehouse','transaction_date','posting_date','voucher_type','voucher_no','actual_qty','company','fiscal_year']
|
||||
for k in mandatory:
|
||||
if self.doc.fields.get(k)==None:
|
||||
msgprint("Stock Ledger Entry: '%s' is mandatory" % k, raise_exception = 1)
|
||||
elif k == 'warehouse':
|
||||
if not sql("select name from tabWarehouse where name = '%s'" % self.doc.fields.get(k)):
|
||||
msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1)
|
||||
|
||||
# validate for item
|
||||
# -----------------
|
||||
|
||||
def validate_item(self):
|
||||
item_det = sql("select name, has_batch_no, docstatus from tabItem where name = '%s'" % self.doc.item_code)
|
||||
|
||||
# check item exists
|
||||
if item_det:
|
||||
item_det = item_det and item_det[0]
|
||||
else:
|
||||
msgprint("Item: '%s' does not exist in the system. Please check." % self.doc.item_code, raise_exception = 1)
|
||||
|
||||
# check if item is trashed
|
||||
if cint(item_det[2])==2:
|
||||
msgprint("Item: '%s' is trashed, cannot make a stock transaction against a trashed item" % self.doc.item_code, raise_exception = 1)
|
||||
|
||||
# check if batch number is required
|
||||
if item_det[1]=='Yes' and self.doc.voucher_type != 'Stock Reconciliation':
|
||||
if not self.doc.batch_no:
|
||||
msgprint("Batch number is mandatory for Item '%s'" % self.doc.item_code, raise_exception = 1)
|
||||
raise Exception
|
||||
|
||||
# check if batch belongs to item
|
||||
if not sql("select name from `tabBatch` where item='%s' and name ='%s' and docstatus != 2" % (self.doc.item_code, self.doc.batch_no)):
|
||||
msgprint("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code), raise_exception = 1)
|
||||
|
||||
# Nobody can do SL Entries where posting date is before freezing date except authorized person
|
||||
#----------------------------------------------------------------------------------------------
|
||||
def check_stock_frozen_date(self):
|
||||
stock_frozen_upto = get_value('Global Defaults', None, 'stock_frozen_upto') or ''
|
||||
if stock_frozen_upto:
|
||||
stock_auth_role = get_value('Global Defaults', None,'stock_auth_role')
|
||||
if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles():
|
||||
msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1)
|
||||
|
||||
def validate_posting_time(self):
|
||||
""" Validate posting time format"""
|
||||
if self.doc.posting_time and len(self.doc.posting_time.split(':')) > 2:
|
||||
msgprint("Wrong format of posting time, can not complete the transaction. If you think \
|
||||
you entered posting time correctly, please contact ERPNext support team.")
|
||||
raise Exception
|
||||
|
||||
def scrub_posting_time(self):
|
||||
if not self.doc.posting_time or self.doc.posting_time == '00:0':
|
||||
self.doc.posting_time = '00:00'
|
||||
if len(self.doc.posting_time.split(':')) > 2:
|
||||
self.doc.posting_time = '00:00'
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.validate_mandatory()
|
||||
self.validate_posting_time()
|
||||
self.validate_item()
|
||||
self.actual_amt_check()
|
||||
self.check_stock_frozen_date()
|
||||
self.scrub_posting_time()
|
||||
421
stock/doctype/stock_ledger_entry/stock_ledger_entry.txt
Normal file
421
stock/doctype/stock_ledger_entry/stock_ledger_entry.txt
Normal file
@@ -0,0 +1,421 @@
|
||||
# DocType, Stock Ledger Entry
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:38',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:38',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1322549701',
|
||||
'autoname': u'SLE/.########',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'hide_toolbar': 1,
|
||||
'in_create': 1,
|
||||
'module': u'Stock',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 53
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Stock Ledger Entry',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Stock Ledger Entry',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Stock Ledger Entry
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Stock Ledger Entry'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Material User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# 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': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Text',
|
||||
'in_filter': 0,
|
||||
'label': u'Serial No',
|
||||
'permlevel': 0,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'batch_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Batch No',
|
||||
'oldfieldname': u'batch_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Warehouse',
|
||||
'oldfieldname': u'warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 1,
|
||||
'search_index': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'warehouse_type',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Warehouse Type',
|
||||
'oldfieldname': u'warehouse_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Warehouse Type',
|
||||
'permlevel': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'description': u'The date at which current entry will get or has actually executed.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'posting_date',
|
||||
'fieldtype': u'Date',
|
||||
'in_filter': 1,
|
||||
'label': u'Posting Date',
|
||||
'oldfieldname': u'posting_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'posting_time',
|
||||
'fieldtype': u'Time',
|
||||
'in_filter': 0,
|
||||
'label': u'Posting Time',
|
||||
'oldfieldname': u'posting_time',
|
||||
'oldfieldtype': u'Time',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'description': u'The date at which current entry is made in system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transaction_date',
|
||||
'fieldtype': u'Date',
|
||||
'in_filter': 1,
|
||||
'label': u'Transaction Date',
|
||||
'oldfieldname': u'transaction_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'voucher_type',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Voucher Type',
|
||||
'oldfieldname': u'voucher_type',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'voucher_no',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Voucher No',
|
||||
'oldfieldname': u'voucher_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'voucher_detail_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Voucher Detail No',
|
||||
'oldfieldname': u'voucher_detail_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'actual_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 1,
|
||||
'label': u'Actual Quantity',
|
||||
'oldfieldname': u'actual_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'incoming_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Incoming Rate',
|
||||
'oldfieldname': u'incoming_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Stock UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'bin_aqat',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 1,
|
||||
'label': u'Bin Actual Qty After Transaction',
|
||||
'oldfieldname': u'bin_aqat',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ma_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Moving Average Rate',
|
||||
'oldfieldname': u'ma_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fcfs_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'FIFO Rate',
|
||||
'oldfieldname': u'fcfs_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'valuation_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Valuation Rate',
|
||||
'oldfieldname': u'valuation_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_value',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Stock Value',
|
||||
'oldfieldname': u'stock_value',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fcfs_stack',
|
||||
'fieldtype': u'Text',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'FIFO Stack',
|
||||
'oldfieldname': u'fcfs_stack',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 2,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Data',
|
||||
'options': u'link:Company',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'is_cancelled',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Is Cancelled',
|
||||
'oldfieldname': u'is_cancelled',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nYes\nNo',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'is_stock_entry',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Is Stock Entry',
|
||||
'oldfieldname': u'is_stock_entry',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nYes\nNo',
|
||||
'permlevel': 1,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
}
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user