diff --git a/erpnext/patches/jan_mar_2012/deploy_packing_slip.py b/erpnext/patches/jan_mar_2012/deploy_packing_slip.py
new file mode 100644
index 0000000000..94bda6eea5
--- /dev/null
+++ b/erpnext/patches/jan_mar_2012/deploy_packing_slip.py
@@ -0,0 +1,48 @@
+import webnotes
+from webnotes.modules.module_manager import reload_doc
+
+def execute():
+ delete_fields_dn_detail()
+ deploy_packing_slip()
+ del_packing_slip_pf()
+
+
+def delete_fields_dn_detail():
+ """
+ Delete old fields related to packing slip
+ """
+ from webnotes.model import delete_fields
+ delete_fields({
+ 'Delivery Note': [
+ 'print_packing_slip', 'shipping_mark', 'packed_by',
+ 'packing_checked_by', 'Text', 'pack_size'
+ ],
+ 'Delivery Note Detail': [
+ 'pack_no', 'pack_gross_wt', 'weight_uom',
+ 'pack_nett_wt', 'no_of_packs', 'pack_unit', 'pack_size',
+ 'packed_by', 'packing_checked_by'
+ ]
+ }, delete=1)
+ delete_fields({'Item': ['nett_weight', 'gross_weight']}, delete=1)
+ reload_doc('stock', 'doctype', 'delivery_note')
+ reload_doc('stock', 'doctype', 'delivery_note_detail')
+ reload_doc('stock', 'doctype', 'item')
+
+
+def deploy_packing_slip():
+ reload_doc('stock', 'doctype', 'packing_slip')
+ reload_doc('stock', 'doctype', 'packing_slip_detail')
+ reload_doc('stock', 'Module Def', 'Stock')
+ reload_doc('stock', 'DocType Mapper', 'Delivery Note-Packing Slip')
+
+
+def del_packing_slip_pf():
+ """
+ Delete Print Format: 'Delivery Note Packing List Wise'
+ """
+ webnotes.conn.sql("""\
+ DELETE FROM `tabDocFormat`
+ WHERE parent='Delivery Note'
+ AND format='Delivery Note Packing List Wise'""")
+ from webnotes.model import delete_doc
+ delete_doc('Print Format', 'Delivery Note Packing List Wise')
diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py
index c05912b098..f5698130da 100644
--- a/erpnext/patches/patch_list.py
+++ b/erpnext/patches/patch_list.py
@@ -60,4 +60,9 @@ patch_list = [
'patch_file': 'cancel_purchase_returned',
'description': "Set docstatus = 2 where status = 'Purchase Returned' for serial no"
},
+ {
+ 'patch_module': 'patches.jan_mar_2012',
+ 'patch_file': 'deploy_packing_slip',
+ 'description': "Delete old packing slip fields & print format & deploy new doctypes related to Packing Slip"
+ },
]
diff --git a/erpnext/selling/doctype/sales_common/sales_common.js b/erpnext/selling/doctype/sales_common/sales_common.js
index a2f276036c..8876fa48f7 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.js
+++ b/erpnext/selling/doctype/sales_common/sales_common.js
@@ -5,11 +5,6 @@
// cur_frm.cscript.other_fname - Other Charges fieldname
// cur_frm.cscript.sales_team_fname - Sales Team fieldname
-function roundNumber(num, dec) {
- var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
- return result;
-}
-
// ============== Load Default Taxes ===================
cur_frm.cscript.load_taxes = function(doc, cdt, cdn) {
// run if this is not executed from dt_map...
diff --git a/erpnext/stock/DocType Mapper/Delivery Note-Packing Slip/Delivery Note-Packing Slip.txt b/erpnext/stock/DocType Mapper/Delivery Note-Packing Slip/Delivery Note-Packing Slip.txt
new file mode 100644
index 0000000000..171e08f807
--- /dev/null
+++ b/erpnext/stock/DocType Mapper/Delivery Note-Packing Slip/Delivery Note-Packing Slip.txt
@@ -0,0 +1,93 @@
+# DocType Mapper, Delivery Note-Packing Slip
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-02-02 11:35:53',
+ 'docstatus': 0,
+ 'modified': '2012-02-02 11:35:53',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all Table Mapper Detail
+ {
+ 'doctype': 'Table Mapper Detail',
+ 'name': '__common__',
+ 'parent': 'Delivery Note-Packing Slip',
+ 'parentfield': 'table_mapper_details',
+ 'parenttype': 'DocType Mapper'
+ },
+
+ # These values are common for all Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'name': '__common__',
+ 'parent': 'Delivery Note-Packing Slip',
+ 'parentfield': 'field_mapper_details',
+ 'parenttype': 'DocType Mapper'
+ },
+
+ # These values are common for all DocType Mapper
+ {
+ 'doctype': u'DocType Mapper',
+ 'from_doctype': 'Delivery Note',
+ 'module': 'Stock',
+ 'name': '__common__',
+ 'ref_doc_submitted': 1,
+ 'to_doctype': 'Packing Slip'
+ },
+
+ # DocType Mapper, Delivery Note-Packing Slip
+ {
+ 'doctype': u'DocType Mapper',
+ 'name': 'Delivery Note-Packing Slip'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'name',
+ 'map': 'Yes',
+ 'match_id': 0,
+ 'to_field': 'delivery_note'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'qty',
+ 'map': 'No',
+ 'match_id': 1,
+ 'to_field': 'qty'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': 'Field Mapper Detail',
+ 'from_field': 'naming_series',
+ 'map': 'No',
+ 'match_id': 0,
+ 'to_field': 'naming_series'
+ },
+
+ # Table Mapper Detail
+ {
+ 'doctype': 'Table Mapper Detail',
+ 'from_table': 'Delivery Note',
+ 'match_id': 0,
+ 'to_table': 'Packing Slip',
+ 'validation_logic': 'docstatus=1'
+ },
+
+ # Table Mapper Detail
+ {
+ 'doctype': 'Table Mapper Detail',
+ 'from_field': 'delivery_note_details',
+ 'from_table': 'Delivery Note Detail',
+ 'match_id': 1,
+ 'to_field': 'item_details',
+ 'to_table': 'Packing Slip Detail',
+ 'validation_logic': 'IFNULL(packed_qty, 0) < IFNULL(qty, 0)'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/stock/Module Def/Stock/Stock.txt b/erpnext/stock/Module Def/Stock/Stock.txt
index 4fc8790480..991d4100b3 100644
--- a/erpnext/stock/Module Def/Stock/Stock.txt
+++ b/erpnext/stock/Module Def/Stock/Stock.txt
@@ -5,7 +5,7 @@
{
'creation': '2011-07-01 17:40:49',
'docstatus': 0,
- 'modified': '2011-10-10 17:01:34',
+ 'modified': '2012-02-01 15:43:00',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -88,6 +88,16 @@
'fields': 'status\ntransaction_date\ncustomer\nterritory\ngrand_total\nper_billed'
},
+ # Module Def Item
+ {
+ 'description': 'Generate Packing Slips based on a Delivery Note',
+ 'display_name': 'Packing Slip',
+ 'doc_name': 'Packing Slip',
+ 'doc_type': 'Forms',
+ 'doctype': 'Module Def Item',
+ 'fields': 'delivery_note\nfrom_case_no\nto_case_no\nnet_weight_pkg\ngross_weight_pkg'
+ },
+
# Module Def Item
{
'description': 'Record of incoming material from your suppliers',
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 5cb4276ba1..59dff8a954 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -46,6 +46,10 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
cur_frm.add_custom_button('Send SMS', cur_frm.cscript['Send SMS']);
unhide_field(['SMS','Send SMS', 'message', 'customer_mobile_no', 'Repair Delivery Note']);
}
+
+ if(doc.docstatus==1) {
+ cur_frm.add_custom_button('Make Packing Slip', cur_frm.cscript['Make Packing Slip']);
+ }
set_print_hide(doc, cdt, cdn);
}
@@ -280,6 +284,23 @@ cur_frm.cscript['Make Installation Note'] = function() {
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 Detail','Packing Slip Detail']]"
+ }, function(r,rt) {
+ loaddoc('Packing Slip', n);
+ }
+ );
+}
+
+
//get query select Territory
//=======================================================================================================================
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 8fc1abcb2f..f7918939cc 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -171,9 +171,6 @@ class DocType(TransactionBase):
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 Net Weight of each Packing
- self.update_pack_nett_weight()
- self.print_packing_slip()
# ::::::: Set actual qty for each item in selected warehouse :::::::
self.update_current_stock()
# :::::: set DN status :::::::
@@ -340,6 +337,7 @@ class DocType(TransactionBase):
self.update_stock_ledger(update_stock = -1)
# :::::: set DN status :::::::
set(self.doc, 'status', 'Cancelled')
+ self.cancel_packing_slips()
# ******************** Check Next DocStatus **************************
@@ -355,6 +353,23 @@ class DocType(TransactionBase):
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])
+
+
# UPDATE STOCK LEDGER
# =================================================================================================
def update_stock_ledger(self, update_stock, is_stopped = 0):
@@ -432,84 +447,3 @@ class DocType(TransactionBase):
def repair_delivery_note(self):
get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self)
- # Packing Slip Related
- # ==========================================
- def update_pack_nett_weight(self):
- for d in getlist(self.doclist, 'delivery_note_details'):
- if d.item_code and not d.pack_nett_wt:
- item_wt = sql("select nett_weight from `tabItem` where name = %s", (d.item_code))
- d.pack_nett_wt = item_wt and flt(item_wt[0][0]) or 0
-
-
- # ==========================================
- def get_header(self, so_no, shipping_mark):
- header = '''
-
[HEADER GOES HERE]
- Packing Slip
-
-
- ORDER NO. |
- '''+cstr(so_no)+''' |
- SHIPPING MARKS |
- '''+cstr(shipping_mark)+''' |
-
-
''';
-
- return header
-
- def get_footer(self, row, tot_nett, tot_gross):
- footer = '''
-
-
- CASE NO | '''+cstr(row.pack_no)+''' |
- NETT WT | '''+cstr(tot_nett)+''' |
- CHECKED BY | '''+cstr(row.packing_checked_by)+''' |
-
-
- SIZE | '''+cstr(row.pack_size)+''' |
- GROSS WT | '''+cstr(tot_gross)+''' |
- PACKED BY | '''+cstr(row.packed_by)+''' |
-
-
'''
-
- return footer
-
- def print_packing_slip(self):
- plist = {}
- for d in getlist(self.doclist, 'delivery_note_details'):
- if not plist.has_key(cstr(d.pack_no)):
- plist[cstr(d.pack_no)] = [d]
- else:
- plist.get(cstr(d.pack_no)).append(d)
-
- html=''
-
- for d in sorted(plist.keys()):
- tot_nett_wt,tot_gross_wt=0,0
-
- # header
- html += self.get_header(self.doc.sales_order_no, self.doc.shipping_mark)
-
- # item table header
- html += '''
-
-
- SR.NO. | CS.NO. | DESCRIPTION |
- QUANTITY | WEIGHT |
-
'''
-
- # item table data
- sr_no = 1
- for r in plist.get(d):
- html += ''+cstr(sr_no)+' | '+r.item_code+' | '+r.description+' | '+cstr(r.qty)+' | '+cstr(r.pack_nett_wt)+' |
'
-
- tot_nett_wt += flt(r.pack_nett_wt)
- tot_gross_wt += flt(r.pack_gross_wt)
-
- sr_no += 1
-
- html += '
'
-
- # footer
- html += self.get_footer(r, tot_nett_wt, tot_gross_wt)
- self.doc.print_packing_slip=html
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt
index 3078bf6ff2..00bf9a8d19 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.txt
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt
@@ -5,7 +5,7 @@
{
'creation': '2011-04-18 15:58:20',
'docstatus': 0,
- 'modified': '2012-01-09 16:52:43',
+ 'modified': '2012-01-30 16:52:12',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -21,7 +21,7 @@
# These values are common for all DocType
{
- '_last_update': '1326105502',
+ '_last_update': '1326273792',
'colour': 'White:FFF',
'default_print_format': 'Standard',
'doctype': 'DocType',
@@ -37,7 +37,7 @@
'show_in_menu': 0,
'subject': 'To %(customer_name)s on %(transaction_date)s | %(per_billed)s% billed',
'tag_fields': 'billing_status',
- 'version': 463
+ 'version': 464
},
# These values are common for all DocFormat
@@ -1433,53 +1433,5 @@
'options': 'repair_delivery_note',
'permlevel': 0,
'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'print_packing_slip',
- 'fieldtype': 'Text',
- 'hidden': 1,
- 'in_filter': 0,
- 'label': 'Print Packing Slip',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'shipping_mark',
- 'fieldtype': 'Text',
- 'label': 'Shipping Mark',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'packed_by',
- 'fieldtype': 'Text',
- 'label': 'Packed By',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'packing_checked_by',
- 'fieldtype': 'Text',
- 'label': 'Packing Checked By',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'pack_size',
- 'fieldtype': 'Text',
- 'label': 'Pack Size',
- 'permlevel': 0
}
]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt b/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
index 806803f73a..a10d1d6aca 100644
--- a/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
+++ b/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
@@ -5,7 +5,7 @@
{
'creation': '2010-08-08 17:08:58',
'docstatus': 0,
- 'modified': '2011-10-18 16:32:44',
+ 'modified': '2012-02-01 16:08:06',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
@@ -23,7 +23,7 @@
'section_style': 'Tray',
'server_code_error': ' ',
'show_in_menu': 0,
- 'version': 43
+ 'version': 51
},
# These values are common for all DocField
@@ -289,104 +289,6 @@
'width': '150px'
},
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'pack_no',
- 'fieldtype': 'Data',
- 'label': 'Pack No',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'pack_gross_wt',
- 'fieldtype': 'Float',
- 'label': 'Pack Gross Wt',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'weight_uom',
- 'fieldtype': 'Link',
- 'label': 'Weight UOM',
- 'options': 'UOM',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'pack_nett_wt',
- 'fieldtype': 'Float',
- 'label': 'Pack Nett Wt',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'no_of_packs',
- 'fieldtype': 'Int',
- 'label': 'No of Packs',
- 'oldfieldname': 'no_of_packs',
- 'oldfieldtype': 'Int',
- 'permlevel': 0,
- 'print_hide': 1,
- 'width': '100px'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'pack_unit',
- 'fieldtype': 'Data',
- 'label': 'Pack Unit',
- 'oldfieldname': 'pack_unit',
- 'oldfieldtype': 'Data',
- 'permlevel': 0,
- 'print_hide': 1,
- 'width': '100px'
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'pack_size',
- 'fieldtype': 'Data',
- 'label': 'Pack Size',
- 'no_copy': 0,
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'packed_by',
- 'fieldtype': 'Data',
- 'label': 'Packed By',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'packing_checked_by',
- 'fieldtype': 'Data',
- 'label': 'Packing Checked By',
- 'permlevel': 0,
- 'print_hide': 1
- },
-
# DocField
{
'doctype': 'DocField',
@@ -504,6 +406,20 @@
'print_hide': 1
},
+ # DocField
+ {
+ 'allow_on_submit': 1,
+ 'colour': 'White:FFF',
+ 'default': '0',
+ 'doctype': 'DocField',
+ 'fieldname': 'packed_qty',
+ 'fieldtype': 'Currency',
+ 'label': 'Packed Quantity',
+ 'no_copy': 1,
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
# DocField
{
'allow_on_submit': 1,
diff --git a/erpnext/stock/doctype/item/item.txt b/erpnext/stock/doctype/item/item.txt
index d6ac71badd..db04bcf88a 100644
--- a/erpnext/stock/doctype/item/item.txt
+++ b/erpnext/stock/doctype/item/item.txt
@@ -5,14 +5,14 @@
{
'creation': '2010-08-08 17:09:05',
'docstatus': 0,
- 'modified': '2012-01-17 18:39:39',
+ 'modified': '2012-01-30 17:34:23',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all DocType
{
- '_last_update': '1325570647',
+ '_last_update': '1326963484',
'allow_attach': 1,
'allow_trash': 1,
'autoname': 'field:item_code',
@@ -29,7 +29,7 @@
'show_in_menu': 0,
'subject': '%(item_name)s',
'tag_fields': 'item_group',
- 'version': 164
+ 'version': 165
},
# These values are common for all DocField
@@ -467,19 +467,11 @@
# DocField
{
+ 'description': 'Net Weight of each Item',
'doctype': 'DocField',
- 'fieldname': 'nett_weight',
+ 'fieldname': 'net_weight',
'fieldtype': 'Float',
- 'label': 'Nett Weight',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': 'DocField',
- 'fieldname': 'gross_weight',
- 'fieldtype': 'Float',
- 'label': 'Gross Weight',
+ 'label': 'Net Weight',
'permlevel': 0
},
diff --git a/erpnext/stock/doctype/packing_slip/__init__.py b/erpnext/stock/doctype/packing_slip/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.js b/erpnext/stock/doctype/packing_slip/packing_slip.js
new file mode 100644
index 0000000000..1bf1f2e5c8
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.js
@@ -0,0 +1,123 @@
+cur_frm.fields_dict['delivery_note'].get_query = function(doc, cdt, cdn) {
+ return 'SELECT name FROM `tabDelivery Note` WHERE docstatus=1 AND %(key)s LIKE "%s"';
+}
+
+
+cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
+ return 'SELECT name, description FROM `tabItem` WHERE name IN ( \
+ SELECT item_code FROM `tabDelivery Note Detail` \
+ WHERE parent="' + doc.delivery_note + '") AND %(key)s LIKE "%s" LIMIT 50';
+}
+
+
+// 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 Detail', doc.name, 'item_details');
+ if(!(flt(ps_detail[0].net_weight) && cstr(ps_detail[0].weight_uom))) {
+ cur_frm.cscript.update_item_details(doc);
+ refresh_field('naming_series');
+ }
+ }
+}
+
+
+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_field('item_details');
+ }
+ });
+}
+
+
+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 Detail', 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; iFrom Case No. = %s""" % (cint(recommended_case_no[0][0]) + 1),
+ raise_exception=1)
+
+
+ def validate_qty(self):
+ """
+ Check packed qty across packing slips and delivery note
+ """
+ # Get Delivery Note Details, 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 Details' 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])
+
+ 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 Detail`
+ 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.
+ Recommended quantity for %(item_code)s = %(recommended_qty)s \
+ %(stock_uom)s""" % 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 Details, 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 Detail`
+ 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 Detail
+ """
+ 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)
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.txt b/erpnext/stock/doctype/packing_slip/packing_slip.txt
new file mode 100644
index 0000000000..6c54a9dfb3
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.txt
@@ -0,0 +1,314 @@
+# DocType, Packing Slip
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-01-30 12:13:10',
+ 'docstatus': 0,
+ 'modified': '2012-02-02 10:37:15',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all DocType
+ {
+ '_last_update': '1328091392',
+ 'autoname': 'PS.#######',
+ 'colour': 'White:FFF',
+ 'doctype': 'DocType',
+ 'document_type': 'Transaction',
+ 'is_transaction_doc': 1,
+ 'module': 'Stock',
+ 'name': '__common__',
+ 'read_only_onload': 1,
+ 'search_fields': 'delivery_note',
+ 'section_style': 'Simple',
+ 'show_in_menu': 0,
+ 'subject': '[%(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': 40
+ },
+
+ # These values are common for all DocField
+ {
+ 'doctype': 'DocField',
+ 'name': '__common__',
+ 'parent': 'Packing Slip',
+ 'parentfield': 'fields',
+ 'parenttype': 'DocType'
+ },
+
+ # These values are common for all DocPerm
+ {
+ 'doctype': 'DocPerm',
+ 'name': '__common__',
+ 'parent': 'Packing Slip',
+ 'parentfield': 'permissions',
+ 'parenttype': 'DocType',
+ 'read': 1
+ },
+
+ # DocType, Packing Slip
+ {
+ 'doctype': 'DocType',
+ 'name': 'Packing Slip'
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Material User',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Sales User',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Material Master Manager',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Material Manager',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': 'DocPerm',
+ 'permlevel': 0,
+ 'role': 'Sales Manager',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'doctype': 'DocPerm',
+ 'permlevel': 1,
+ 'role': 'All'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Packing Slip Details',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'delivery_note',
+ 'fieldtype': 'Link',
+ 'label': 'Delivery Note',
+ 'options': 'Delivery Note',
+ 'permlevel': 0,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'naming_series',
+ 'fieldtype': 'Select',
+ 'label': 'Series',
+ 'no_copy': 0,
+ 'options': 'PS',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'from_case_no',
+ 'fieldtype': 'Data',
+ 'label': 'From Case No.',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'width': '50px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'to_case_no',
+ 'fieldtype': 'Data',
+ 'label': 'To Case No.',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'width': '50px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Package Item Details',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'item_details',
+ 'fieldtype': 'Table',
+ 'label': 'Items',
+ 'options': 'Packing Slip Detail',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Package Weight Details',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'net_weight_pkg',
+ 'fieldtype': 'Currency',
+ 'label': 'Net Weight',
+ 'no_copy': 1,
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'net_weight_uom',
+ 'fieldtype': 'Data',
+ 'label': 'Net Weight UOM',
+ 'no_copy': 1,
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldtype': 'Column Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'gross_weight_pkg',
+ 'fieldtype': 'Currency',
+ 'label': 'Gross Weight',
+ 'no_copy': 1,
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': 'White:FFF',
+ 'doctype': 'DocField',
+ 'fieldname': 'gross_weight_uom',
+ 'fieldtype': 'Link',
+ 'label': 'Gross Weight UOM',
+ 'no_copy': 1,
+ 'options': 'UOM',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'depends_on': 'eval:doc.amended_from',
+ 'doctype': 'DocField',
+ 'fieldtype': 'Section Break',
+ 'label': 'Misc Details',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'amended_from',
+ 'fieldtype': 'Link',
+ 'label': 'Amended From',
+ 'no_copy': 1,
+ 'options': 'Packing Slip',
+ 'permlevel': 1,
+ 'print_hide': 1
+ }
+]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/packing_slip_detail/__init__.py b/erpnext/stock/doctype/packing_slip_detail/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.py b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.py
new file mode 100644
index 0000000000..05f502c70f
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.py
@@ -0,0 +1,29 @@
+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 Detail`
+ 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)
diff --git a/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.txt b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.txt
new file mode 100644
index 0000000000..5a83b6f35f
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.txt
@@ -0,0 +1,113 @@
+# DocType, Packing Slip Detail
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-01-30 17:40:50',
+ 'docstatus': 0,
+ 'modified': '2012-01-31 13:15:40',
+ 'modified_by': 'Administrator',
+ 'owner': 'Administrator'
+ },
+
+ # These values are common for all DocType
+ {
+ 'autoname': 'PSD/.#######',
+ 'colour': 'White:FFF',
+ 'doctype': 'DocType',
+ 'istable': 1,
+ 'module': 'Stock',
+ 'name': '__common__',
+ 'section_style': 'Simple',
+ 'show_in_menu': 0,
+ 'version': 9
+ },
+
+ # These values are common for all DocField
+ {
+ 'doctype': 'DocField',
+ 'name': '__common__',
+ 'parent': 'Packing Slip Detail',
+ 'parentfield': 'fields',
+ 'parenttype': 'DocType'
+ },
+
+ # DocType, Packing Slip Detail
+ {
+ 'doctype': 'DocType',
+ 'name': 'Packing Slip Detail'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'item_code',
+ 'fieldtype': 'Link',
+ 'label': 'Item Code',
+ 'options': 'Item',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'item_name',
+ 'fieldtype': 'Data',
+ 'label': 'Item Name',
+ 'permlevel': 1,
+ 'width': '200px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'qty',
+ 'fieldtype': 'Currency',
+ 'label': 'Quantity',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'stock_uom',
+ 'fieldtype': 'Data',
+ 'label': 'UOM',
+ 'permlevel': 1,
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'net_weight',
+ 'fieldtype': 'Float',
+ 'label': 'Net Weight',
+ 'permlevel': 1,
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'weight_uom',
+ 'fieldtype': 'Link',
+ 'label': 'Weight UOM',
+ 'options': 'UOM',
+ 'permlevel': 1,
+ 'width': '100px'
+ },
+
+ # DocField
+ {
+ 'doctype': 'DocField',
+ 'fieldname': 'page_break',
+ 'fieldtype': 'Check',
+ 'label': 'Page Break',
+ 'permlevel': 0
+ }
+]
\ No newline at end of file
diff --git a/index.html b/index.html
index 94822ef44e..2793bd71b0 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
ERPNext
-