mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 03:39:11 +00:00
Merge branch 'master' into dev
Conflicts: erpnext/support/doctype/maintenance_visit/maintenance_visit.py
This commit is contained in:
@@ -48,11 +48,6 @@
|
|||||||
title="Export multiple Account Ledgers (GL) to spreadsheet (csv)"
|
title="Export multiple Account Ledgers (GL) to spreadsheet (csv)"
|
||||||
href="#!Form/Multi Ledger Report/Multi Ledger Report">Export Multiple Ledgers (GL)</a>
|
href="#!Form/Multi Ledger Report/Multi Ledger Report">Export Multiple Ledgers (GL)</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-item">
|
|
||||||
<a class="section-link"
|
|
||||||
title="Lease Agreements"
|
|
||||||
href="#!List/Lease Agreement">Lease Agreements</a>
|
|
||||||
</div>
|
|
||||||
<div class="section-item">
|
<div class="section-item">
|
||||||
<a class="section-link"
|
<a class="section-link"
|
||||||
title = "Helper for managing return of goods (sales or purchase)"
|
title = "Helper for managing return of goods (sales or purchase)"
|
||||||
|
|||||||
@@ -363,45 +363,63 @@ class DocType(TransactionBase):
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# --------------
|
|
||||||
# get item list
|
|
||||||
# --------------
|
|
||||||
def get_item_list(self, obj, is_stopped):
|
def get_item_list(self, obj, is_stopped):
|
||||||
|
"""get item list"""
|
||||||
il = []
|
il = []
|
||||||
for d in getlist(obj.doclist,obj.fname):
|
for d in getlist(obj.doclist,obj.fname):
|
||||||
reserved_qty = 0 # used for delivery note
|
reserved_wh, reserved_qty = '', 0 # used for delivery note
|
||||||
qty = flt(d.qty)
|
qty = flt(d.qty)
|
||||||
if is_stopped:
|
if is_stopped:
|
||||||
qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0
|
qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0
|
||||||
|
|
||||||
if d.prevdoc_doctype == 'Sales Order': # used in delivery note to reduce reserved_qty
|
if d.prevdoc_doctype == 'Sales Order':
|
||||||
|
# used in delivery note to reduce reserved_qty
|
||||||
# Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
|
# Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
|
||||||
# But in this case reserved qty should only be reduced by 10 and not 12.
|
# But in this case reserved qty should only be reduced by 10 and not 12.
|
||||||
|
|
||||||
tot_qty, max_qty, tot_amt, max_amt = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, 'Sales Order Item', obj.doc.name, obj.doc.doctype)
|
tot_qty, max_qty, tot_amt, max_amt, reserved_wh = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, obj.doc.name, obj.doc.doctype)
|
||||||
if((flt(tot_qty) + flt(qty) > flt(max_qty))):
|
if((flt(tot_qty) + flt(qty) > flt(max_qty))):
|
||||||
reserved_qty = -(flt(max_qty)-flt(tot_qty))
|
reserved_qty = -(flt(max_qty)-flt(tot_qty))
|
||||||
else:
|
else:
|
||||||
reserved_qty = - flt(qty)
|
reserved_qty = - flt(qty)
|
||||||
|
|
||||||
warehouse = (obj.fname == "sales_order_details") and d.reserved_warehouse or d.warehouse
|
if obj.doc.doctype == 'Sales Order':
|
||||||
|
reserved_wh = d.reserved_warehouse
|
||||||
|
|
||||||
if self.has_sales_bom(d.item_code):
|
if self.has_sales_bom(d.item_code):
|
||||||
for p in getlist(obj.doclist, 'packing_details'):
|
for p in getlist(obj.doclist, 'packing_details'):
|
||||||
#if p.parent_item == d.item_code: -- this fails when item with same name appears more than once in delivery note item table
|
|
||||||
if p.parent_detail_docname == d.name:
|
if p.parent_detail_docname == d.name:
|
||||||
# the packing details table's qty is already multiplied with parent's qty
|
# the packing details table's qty is already multiplied with parent's qty
|
||||||
il.append([warehouse, p.item_code, flt(p.qty), (flt(p.qty)/qty)*(reserved_qty), p.uom, p.batch_no, p.serial_no])
|
il.append({
|
||||||
|
'warehouse': d.warehouse,
|
||||||
|
'reserved_warehouse': reserved_wh,
|
||||||
|
'item_code': p.item_code,
|
||||||
|
'qty': flt(p.qty),
|
||||||
|
'reserved_qty': (flt(p.qty)/qty)*(reserved_qty),
|
||||||
|
'uom': p.uom,
|
||||||
|
'batch_no': p.batch_no,
|
||||||
|
'serial_no': p.serial_no
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
il.append([warehouse, d.item_code, qty, reserved_qty, d.stock_uom, d.batch_no, d.serial_no])
|
il.append({
|
||||||
|
'warehouse': d.warehouse,
|
||||||
|
'reserved_warehouse': reserved_wh,
|
||||||
|
'item_code': d.item_code,
|
||||||
|
'qty': qty,
|
||||||
|
'reserved_qty': reserved_qty,
|
||||||
|
'uom': d.stock_uom,
|
||||||
|
'batch_no': d.batch_no,
|
||||||
|
'serial_no': d.serial_no
|
||||||
|
})
|
||||||
return il
|
return il
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------------
|
|
||||||
# get qty, amount already billed or delivered against curr line item for current doctype
|
def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name, curr_parent_doctype):
|
||||||
# For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV
|
""" Get qty, amount already billed or delivered against curr line item for current doctype
|
||||||
# ---------------------------------------------------------------------------------------------
|
For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV
|
||||||
def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, ref_doc_tname, curr_parent_name, curr_parent_doctype):
|
"""
|
||||||
# Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction
|
#Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction
|
||||||
if curr_parent_doctype == 'Installation Note':
|
if curr_parent_doctype == 'Installation Note':
|
||||||
curr_det = webnotes.conn.sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
|
curr_det = webnotes.conn.sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
|
||||||
qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0
|
qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0
|
||||||
@@ -410,10 +428,9 @@ class DocType(TransactionBase):
|
|||||||
qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0
|
qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0
|
||||||
|
|
||||||
# get total qty of ref doctype
|
# get total qty of ref doctype
|
||||||
ref_det = webnotes.conn.sql("select qty, amount from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn))
|
so_det = webnotes.conn.sql("select qty, amount, reserved_warehouse from `tabSales Order Item` where name = '%s' and docstatus = 1"% ref_tab_dn)
|
||||||
max_qty, max_amt = ref_det and flt(ref_det[0][0]) or 0, ref_det and flt(ref_det[0][1]) or 0
|
max_qty, max_amt, res_wh = so_det and flt(so_det[0][0]) or 0, so_det and flt(so_det[0][1]) or 0, so_det and cstr(so_det[0][2]) or ''
|
||||||
|
return qty, max_qty, amt, max_amt, res_wh
|
||||||
return qty, max_qty, amt, max_amt
|
|
||||||
|
|
||||||
|
|
||||||
# Make Packing List from Sales BOM
|
# Make Packing List from Sales BOM
|
||||||
|
|||||||
@@ -458,12 +458,15 @@ class DocType(TransactionBase):
|
|||||||
# ===============================================================================================
|
# ===============================================================================================
|
||||||
def update_stock_ledger(self, update_stock, clear = 0):
|
def update_stock_ledger(self, update_stock, clear = 0):
|
||||||
for d in self.get_item_list(clear):
|
for d in self.get_item_list(clear):
|
||||||
stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d[1]),as_dict = 1) # stock ledger will be updated only if it is a stock item
|
stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d['item_code']),as_dict = 1)
|
||||||
|
# stock ledger will be updated only if it is a stock item
|
||||||
if stock_item and stock_item[0]['is_stock_item'] == "Yes":
|
if stock_item and stock_item[0]['is_stock_item'] == "Yes":
|
||||||
if not d[0]:
|
if not d['reserved_warehouse']:
|
||||||
msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1])
|
msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d['item_code'])
|
||||||
raise Exception
|
raise Exception
|
||||||
bin = get_obj('Warehouse', d[0]).update_bin( 0, flt(update_stock) * flt(d[2]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
|
bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin( 0, flt(update_stock) * flt(d['qty']), \
|
||||||
|
0, 0, 0, d['item_code'], self.doc.transaction_date,doc_type=self.doc.doctype,\
|
||||||
|
doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
|
||||||
|
|
||||||
# Gets Items from packing list
|
# Gets Items from packing list
|
||||||
#=================================
|
#=================================
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ class DocType:
|
|||||||
|
|
||||||
self.create_feed_and_todo()
|
self.create_feed_and_todo()
|
||||||
|
|
||||||
|
self.create_email_digest()
|
||||||
|
|
||||||
webnotes.clear_cache()
|
webnotes.clear_cache()
|
||||||
msgprint("Company setup is complete")
|
msgprint("Company setup is complete")
|
||||||
|
|
||||||
@@ -127,6 +129,44 @@ class DocType:
|
|||||||
d.reference_type = 'Supplier'
|
d.reference_type = 'Supplier'
|
||||||
d.save(1)
|
d.save(1)
|
||||||
|
|
||||||
|
def create_email_digest(self):
|
||||||
|
"""
|
||||||
|
create a default weekly email digest
|
||||||
|
* Weekly Digest
|
||||||
|
* For all companies
|
||||||
|
* Recipients: System Managers
|
||||||
|
* Full content
|
||||||
|
* Enabled by default
|
||||||
|
"""
|
||||||
|
import webnotes
|
||||||
|
companies_list = webnotes.conn.sql("SELECT company_name FROM `tabCompany`", as_list=1)
|
||||||
|
|
||||||
|
import webnotes.utils
|
||||||
|
system_managers = webnotes.utils.get_system_managers_list()
|
||||||
|
if not system_managers: return
|
||||||
|
|
||||||
|
from webnotes.model.doc import Document
|
||||||
|
for company in companies_list:
|
||||||
|
if company and company[0]:
|
||||||
|
edigest = Document('Email Digest')
|
||||||
|
edigest.name = "Default Weekly Digest - " + company[0]
|
||||||
|
edigest.company = company[0]
|
||||||
|
edigest.frequency = 'Weekly'
|
||||||
|
edigest.recipient_list = "\n".join(system_managers)
|
||||||
|
for f in ['new_leads', 'new_enquiries', 'new_quotations',
|
||||||
|
'new_sales_orders', 'new_purchase_orders',
|
||||||
|
'new_transactions', 'payables', 'payments',
|
||||||
|
'expenses_booked', 'invoiced_amount', 'collections',
|
||||||
|
'income', 'bank_balance', 'stock_below_rl',
|
||||||
|
'income_year_to_date', 'enabled']:
|
||||||
|
edigest.fields[f] = 1
|
||||||
|
exists = webnotes.conn.sql("""\
|
||||||
|
SELECT name FROM `tabEmail Digest`
|
||||||
|
WHERE name = %s""", edigest.name)
|
||||||
|
if (exists and exists[0]) and exists[0][0]:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
edigest.save(1)
|
||||||
|
|
||||||
# Get Fiscal year Details
|
# Get Fiscal year Details
|
||||||
# ------------------------
|
# ------------------------
|
||||||
|
|||||||
@@ -297,13 +297,13 @@ class DocType(TransactionBase):
|
|||||||
# check if same item, warehouse present in prevdoc
|
# check if same item, warehouse present in prevdoc
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
def validate_items_with_prevdoc(self, d):
|
def validate_items_with_prevdoc(self, d):
|
||||||
if d.prevdoc_doctype == 'Sales Order':
|
prev_item_dt = (d.prevdoc_doctype == 'Sales Order') and 'Sales Order Item' or 'Purchase Receipt Item'
|
||||||
data = sql("select item_code, reserved_warehouse from `tabSales Order Item` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname))
|
data = sql("select item_code from `tab%s` where parent = '%s' and name = '%s'"\
|
||||||
if d.prevdoc_doctype == 'Purchase Receipt':
|
% (prev_item_dt, d.prevdoc_docname, d.prevdoc_detail_docname))
|
||||||
data = sql("select item_code, rejected_warehouse from `tabPurchase Receipt Item` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname))
|
if not data or data[0][0] != d.item_code:
|
||||||
if not data or data[0][0] != d.item_code or data[0][1] != d.warehouse:
|
msgprint("Item: %s is not matching with Sales Order: %s. Sales Order might be modified after \
|
||||||
msgprint("Item: %s / Warehouse: %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.warehouse, d.prevdoc_docname))
|
fetching data from it. Please delete items and fetch again." \
|
||||||
raise Exception
|
% (d.item_code, d.prevdoc_docname), raise_exception=1)
|
||||||
|
|
||||||
|
|
||||||
# ********* UPDATE CURRENT STOCK *****************************
|
# ********* UPDATE CURRENT STOCK *****************************
|
||||||
@@ -413,16 +413,19 @@ class DocType(TransactionBase):
|
|||||||
def update_stock_ledger(self, update_stock, is_stopped = 0):
|
def update_stock_ledger(self, update_stock, is_stopped = 0):
|
||||||
self.values = []
|
self.values = []
|
||||||
for d in self.get_item_list(is_stopped):
|
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[1]), as_dict = 1) # stock ledger will be updated only if it is a stock item
|
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 stock_item[0]['is_stock_item'] == "Yes":
|
||||||
if not d[0]:
|
if not d['warehouse']:
|
||||||
msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d[1])
|
msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d['item_code'])
|
||||||
raise Exception
|
raise Exception
|
||||||
if d[3] < 0 :
|
if d['reserved_qty'] < 0 :
|
||||||
# Reduce Reserved Qty from warehouse
|
# Reduce reserved qty from reserved warehouse mentioned in so
|
||||||
bin = get_obj('Warehouse', d[0]).update_bin(0, flt(update_stock) * flt(d[3]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
|
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
|
# Reduce actual qty from warehouse
|
||||||
self.make_sl_entry(d, d[0], - flt(d[2]) , 0, update_stock)
|
self.make_sl_entry(d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
|
||||||
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
|
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
|
||||||
|
|
||||||
|
|
||||||
@@ -434,22 +437,22 @@ class DocType(TransactionBase):
|
|||||||
# ********************** Make Stock Entry ************************************
|
# ********************** Make Stock Entry ************************************
|
||||||
def make_sl_entry(self, d, wh, qty, in_value, update_stock):
|
def make_sl_entry(self, d, wh, qty, in_value, update_stock):
|
||||||
self.values.append({
|
self.values.append({
|
||||||
'item_code' : d[1],
|
'item_code' : d['item_code'],
|
||||||
'warehouse' : wh,
|
'warehouse' : wh,
|
||||||
'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'),
|
'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'),
|
||||||
'posting_date' : self.doc.posting_date,
|
'posting_date' : self.doc.posting_date,
|
||||||
'posting_time' : self.doc.posting_time,
|
'posting_time' : self.doc.posting_time,
|
||||||
'voucher_type' : 'Delivery Note',
|
'voucher_type' : 'Delivery Note',
|
||||||
'voucher_no' : self.doc.name,
|
'voucher_no' : self.doc.name,
|
||||||
'voucher_detail_no' : '',
|
'voucher_detail_no' : '',
|
||||||
'actual_qty' : qty,
|
'actual_qty' : qty,
|
||||||
'stock_uom' : d[4],
|
'stock_uom' : d['uom'],
|
||||||
'incoming_rate' : in_value,
|
'incoming_rate' : in_value,
|
||||||
'company' : self.doc.company,
|
'company' : self.doc.company,
|
||||||
'fiscal_year' : self.doc.fiscal_year,
|
'fiscal_year' : self.doc.fiscal_year,
|
||||||
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
|
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
|
||||||
'batch_no' : d[5],
|
'batch_no' : d['batch_no'],
|
||||||
'serial_no' : d[6]
|
'serial_no' : d['serial_no']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ wn.doclistviews['Purchase Receipt'] = wn.views.ListView.extend({
|
|||||||
{width: '3%', content:'docstatus'},
|
{width: '3%', content:'docstatus'},
|
||||||
{width: '15%', content:'name'},
|
{width: '15%', content:'name'},
|
||||||
{width: '47%', content:'supplier_name+tags', css: {color:'#222'}},
|
{width: '47%', content:'supplier_name+tags', css: {color:'#222'}},
|
||||||
{width: '15%', content:'purchase_order_no', type:'link', doctype:'Purchase Order Order'},
|
{width: '15%', content:'purchase_order_no', type:'link', doctype:'Purchase Order'},
|
||||||
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -60,7 +60,12 @@ class DocType:
|
|||||||
count = 1
|
count = 1
|
||||||
for s in data:
|
for s in data:
|
||||||
count += 1
|
count += 1
|
||||||
if count == 2: continue
|
if count == 2:
|
||||||
|
if s[0] != 'Item Code' or s[1] != 'Warehouse':
|
||||||
|
msgprint("First row of the attachment always should be same as template(Item Code, Warehouse, Quantity \
|
||||||
|
and Valuation Rate/Incoming Rate)", raise_exception=1)
|
||||||
|
else:
|
||||||
|
continue
|
||||||
# validate
|
# validate
|
||||||
if (submit and len(s) != 4) or (not submit and len(s) != 6):
|
if (submit and len(s) != 4) or (not submit and len(s) != 6):
|
||||||
msgprint("Data entered at Row No " + cstr(count) + " in Attachment File is not in correct format.", raise_exception=1)
|
msgprint("Data entered at Row No " + cstr(count) + " in Attachment File is not in correct format.", raise_exception=1)
|
||||||
@@ -172,6 +177,7 @@ class DocType:
|
|||||||
Make stock entry of qty diff, calculate incoming rate to maintain valuation rate.
|
Make stock entry of qty diff, calculate incoming rate to maintain valuation rate.
|
||||||
If no qty diff, but diff in valuation rate, make (+1,-1) entry to update valuation
|
If no qty diff, but diff in valuation rate, make (+1,-1) entry to update valuation
|
||||||
"""
|
"""
|
||||||
|
self.diff_info = ''
|
||||||
for row in self.data:
|
for row in self.data:
|
||||||
# Get qty as per system
|
# Get qty as per system
|
||||||
sys_stock = self.get_system_stock(row[0],row[1])
|
sys_stock = self.get_system_stock(row[0],row[1])
|
||||||
@@ -190,28 +196,27 @@ class DocType:
|
|||||||
self.make_entry_for_valuation(row, sys_stock, is_submit)
|
self.make_entry_for_valuation(row, sys_stock, is_submit)
|
||||||
|
|
||||||
if is_submit == 1:
|
if is_submit == 1:
|
||||||
self.store_diff_info(qty_diff, rate_diff)
|
r = [cstr(i) for i in row] + [cstr(qty_diff), cstr(rate_diff)]
|
||||||
|
self.store_diff_info(r)
|
||||||
|
|
||||||
msgprint("Stock Reconciliation Completed Successfully...")
|
msgprint("Stock Reconciliation Completed Successfully...")
|
||||||
|
|
||||||
|
|
||||||
def store_diff_info(self, qty_diff, rate_diff):
|
def store_diff_info(self, r):
|
||||||
"""Add diffs column in attached file"""
|
"""Add diffs column in attached file"""
|
||||||
|
|
||||||
# add header
|
# add header
|
||||||
if self.val_method == 'Moving Average':
|
if not self.diff_info:
|
||||||
out = "Item Code, Warehouse, Qty, Valuation Rate, Qty Diff, Rate Diff"
|
if self.val_method == 'Moving Average':
|
||||||
else:
|
self.diff_info += "Item Code, Warehouse, Qty, Valuation Rate, Qty Diff, Rate Diff"
|
||||||
out = "Item Code, Warehouse, Qty, Incoming Rate, Qty Diff, Rate Diff"
|
else:
|
||||||
|
self.diff_info += "Item Code, Warehouse, Qty, Incoming Rate, Qty Diff, Rate Diff"
|
||||||
|
|
||||||
|
|
||||||
# add data
|
# add data
|
||||||
for d in self.data:
|
self.diff_info += "\n" + ','.join(r)
|
||||||
s = [cstr(i) for i in d] + [cstr(qty_diff), cstr(rate_diff)]
|
|
||||||
out += "\n" + ','.join(s)
|
|
||||||
|
|
||||||
webnotes.conn.set(self.doc, 'diff_info', out)
|
|
||||||
|
|
||||||
|
webnotes.conn.set(self.doc, 'diff_info', self.diff_info)
|
||||||
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
@@ -221,7 +226,6 @@ class DocType:
|
|||||||
self.do_stock_reco(is_submit = 1)
|
self.do_stock_reco(is_submit = 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.get_reconciliation_data(submit = 0)
|
self.get_reconciliation_data(submit = 0)
|
||||||
self.do_stock_reco(is_submit = -1)
|
self.do_stock_reco(is_submit = -1)
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# DocType Mapper, Maintenance Schedule-Maintenance Visit
|
||||||
|
[
|
||||||
|
|
||||||
|
# These values are common in all dictionaries
|
||||||
|
{
|
||||||
|
'creation': '2012-06-27 13:18:25',
|
||||||
|
'docstatus': 0,
|
||||||
|
'modified': '2012-06-27 13:18:25',
|
||||||
|
'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'Maintenance Schedule-Maintenance Visit',
|
||||||
|
'parentfield': u'table_mapper_details',
|
||||||
|
'parenttype': u'DocType Mapper',
|
||||||
|
'validation_logic': u'docstatus=1'
|
||||||
|
},
|
||||||
|
|
||||||
|
# These values are common for all Field Mapper Detail
|
||||||
|
{
|
||||||
|
'doctype': u'Field Mapper Detail',
|
||||||
|
'map': u'Yes',
|
||||||
|
'name': '__common__',
|
||||||
|
'parent': u'Maintenance Schedule-Maintenance Visit',
|
||||||
|
'parentfield': u'field_mapper_details',
|
||||||
|
'parenttype': u'DocType Mapper'
|
||||||
|
},
|
||||||
|
|
||||||
|
# These values are common for all DocType Mapper
|
||||||
|
{
|
||||||
|
'doctype': u'DocType Mapper',
|
||||||
|
'from_doctype': u'Maintenance Schedule',
|
||||||
|
'module': u'Support',
|
||||||
|
'name': '__common__',
|
||||||
|
'ref_doc_submitted': 1,
|
||||||
|
'to_doctype': u'Maintenance Visit'
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocType Mapper, Maintenance Schedule-Maintenance Visit
|
||||||
|
{
|
||||||
|
'doctype': u'DocType Mapper',
|
||||||
|
'name': u'Maintenance Schedule-Maintenance Visit'
|
||||||
|
},
|
||||||
|
|
||||||
|
# Field Mapper Detail
|
||||||
|
{
|
||||||
|
'checking_operator': u'=',
|
||||||
|
'doctype': u'Field Mapper Detail',
|
||||||
|
'from_field': u'customer',
|
||||||
|
'match_id': 0,
|
||||||
|
'to_field': u'customer'
|
||||||
|
},
|
||||||
|
|
||||||
|
# Field Mapper Detail
|
||||||
|
{
|
||||||
|
'doctype': u'Field Mapper Detail',
|
||||||
|
'from_field': u'name',
|
||||||
|
'match_id': 0,
|
||||||
|
'to_field': u'maintenance_schedule'
|
||||||
|
},
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
},
|
||||||
|
|
||||||
|
# Table Mapper Detail
|
||||||
|
{
|
||||||
|
'doctype': u'Table Mapper Detail',
|
||||||
|
'from_field': u'item_maintenance_detail',
|
||||||
|
'from_table': u'Maintenance Schedule Item',
|
||||||
|
'match_id': 1,
|
||||||
|
'to_field': u'maintenance_visit_details',
|
||||||
|
'to_table': u'Maintenance Visit Purpose'
|
||||||
|
},
|
||||||
|
|
||||||
|
# Table Mapper Detail
|
||||||
|
{
|
||||||
|
'doctype': u'Table Mapper Detail',
|
||||||
|
'from_table': u'Maintenance Schedule',
|
||||||
|
'match_id': 0,
|
||||||
|
'to_table': u'Maintenance Visit'
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -16,16 +16,19 @@
|
|||||||
|
|
||||||
cur_frm.cscript.onload = function(doc, dt, dn) {
|
cur_frm.cscript.onload = function(doc, dt, dn) {
|
||||||
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
||||||
if(doc.customer) cur_frm.cscript.customer(doc,cdt,cdn);
|
if(doc.__islocal) set_multiple(dt,dn,{mntc_date:get_today()});
|
||||||
|
hide_contact_info(doc);
|
||||||
if(doc.__islocal){
|
|
||||||
set_multiple(dt,dn,{mntc_date:get_today()});
|
|
||||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(doc.maintenance_type) cur_frm.cscript.maintenance_type(doc,cdt,cdn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hide_contact_info = function(doc) {
|
||||||
|
if(doc.customer) $(cur_frm.fields_dict.contact_info_section.row.wrapper).toggle(true);
|
||||||
|
else $(cur_frm.fields_dict.contact_info_section.row.wrapper).toggle(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_frm.cscript.refresh = function(doc) {
|
||||||
|
hide_contact_info(doc);
|
||||||
|
}
|
||||||
|
|
||||||
//customer
|
//customer
|
||||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||||
@@ -35,7 +38,7 @@ cur_frm.cscript.customer = function(doc,dt,dn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback);
|
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback);
|
||||||
if(doc.customer) unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
hide_contact_info(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||||
@@ -62,36 +65,12 @@ cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
|||||||
|
|
||||||
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||||
var callback = function(r,rt) {
|
var callback = function(r,rt) {
|
||||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
hide_contact_info(doc);
|
||||||
cur_frm.refresh();
|
cur_frm.refresh();
|
||||||
}
|
}
|
||||||
get_server_fields('fetch_items','','',doc, dt, dn,1,callback);
|
get_server_fields('fetch_items','','',doc, dt, dn,1,callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
cur_frm.cscript.maintenance_type = function(doc,cdt,cdn){
|
|
||||||
if(doc.maintenance_type == 'Scheduled') {
|
|
||||||
hide_field('sales_order_no');
|
|
||||||
hide_field('customer_issue_no');
|
|
||||||
hide_field('Get Items');
|
|
||||||
doc.customer_issue_no = '';
|
|
||||||
doc.sales_order_no = '';
|
|
||||||
}
|
|
||||||
else if(doc.maintenance_type == 'Unscheduled') {
|
|
||||||
unhide_field('sales_order_no');
|
|
||||||
hide_field('customer_issue_no');
|
|
||||||
unhide_field('Get Items');
|
|
||||||
doc.customer_issue_no = '';
|
|
||||||
}
|
|
||||||
else if(doc.maintenance_type == 'Breakdown') {
|
|
||||||
hide_field('sales_order_no');
|
|
||||||
unhide_field('customer_issue_no');
|
|
||||||
unhide_field('Get Items');
|
|
||||||
doc.sales_order_no = '';
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
cur_frm.fields_dict['maintenance_visit_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
cur_frm.fields_dict['maintenance_visit_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
||||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem WHERE tabItem.is_service_item="Yes" AND tabItem.docstatus != 2 AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem WHERE tabItem.is_service_item="Yes" AND tabItem.docstatus != 2 AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||||
}
|
}
|
||||||
@@ -110,7 +89,6 @@ cur_frm.fields_dict['sales_order_no'].get_query = function(doc) {
|
|||||||
if(doc.customer) {
|
if(doc.customer) {
|
||||||
cond = '`tabSales Order`.customer = "'+doc.customer+'" AND';
|
cond = '`tabSales Order`.customer = "'+doc.customer+'" AND';
|
||||||
}
|
}
|
||||||
//return repl('SELECT DISTINCT `tabSales Order`.name FROM `tabSales Order`, `tabSales Order Item` WHERE `tabSales Order`.company = "%(company)s" AND `tabSales Order`.docstatus = 1 AND %(cond)s `tabSales Order`.name LIKE "%s" ORDER BY `tabSales Order`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
|
||||||
return repl('SELECT DISTINCT `tabSales Order`.name FROM `tabSales Order`, `tabSales Order Item`, `tabItem` WHERE `tabSales Order`.company = "%(company)s" AND `tabSales Order`.docstatus = 1 AND `tabSales Order Item`.parent = `tabSales Order`.name AND `tabSales Order Item`.item_code = `tabItem`.name AND `tabItem`.is_service_item = "Yes" AND %(cond)s `tabSales Order`.name LIKE "%s" ORDER BY `tabSales Order`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
return repl('SELECT DISTINCT `tabSales Order`.name FROM `tabSales Order`, `tabSales Order Item`, `tabItem` WHERE `tabSales Order`.company = "%(company)s" AND `tabSales Order`.docstatus = 1 AND `tabSales Order Item`.parent = `tabSales Order`.name AND `tabSales Order Item`.item_code = `tabItem`.name AND `tabItem`.is_service_item = "Yes" AND %(cond)s `tabSales Order`.name LIKE "%s" ORDER BY `tabSales Order`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,8 +101,16 @@ cur_frm.fields_dict['customer_issue_no'].get_query = function(doc) {
|
|||||||
return repl('SELECT `tabCustomer Issue`.name FROM `tabCustomer Issue` WHERE `tabCustomer Issue`.company = "%(company)s" AND %(cond)s `tabCustomer Issue`.docstatus = 1 AND (`tabCustomer Issue`.status = "Open" OR `tabCustomer Issue`.status = "Work In Progress") AND `tabCustomer Issue`.name LIKE "%s" ORDER BY `tabCustomer Issue`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
return repl('SELECT `tabCustomer Issue`.name FROM `tabCustomer Issue` WHERE `tabCustomer Issue`.company = "%(company)s" AND %(cond)s `tabCustomer Issue`.docstatus = 1 AND (`tabCustomer Issue`.status = "Open" OR `tabCustomer Issue`.status = "Work In Progress") AND `tabCustomer Issue`.name LIKE "%s" ORDER BY `tabCustomer Issue`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cur_frm.fields_dict['maintenance_schedule'].get_query = function(doc) {
|
||||||
|
doc = locals[this.doctype][this.docname];
|
||||||
|
var cond = '';
|
||||||
|
if(doc.customer) {
|
||||||
|
cond = '`tabMaintenance Schedule`.customer = "'+doc.customer+'" AND';
|
||||||
|
}
|
||||||
|
return repl('SELECT `tabMaintenance Schedule`.name FROM `tabMaintenance Schedule` WHERE `tabMaintenance Schedule`.company = "%(company)s" AND %(cond)s `tabMaintenance Schedule`.docstatus = 1 AND `tabMaintenance Schedule`.name LIKE "%s" ORDER BY `tabMaintenance Schedule`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
||||||
|
}
|
||||||
|
|
||||||
//get query select Territory
|
//get query select Territory
|
||||||
//=======================================================================================================================
|
|
||||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
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';
|
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';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Please edit this list and import only required elements
|
# Please edit this list and import only required elements
|
||||||
import webnotes
|
import webnotes
|
||||||
@@ -35,130 +35,129 @@ convert_to_lists = webnotes.conn.convert_to_lists
|
|||||||
from utilities.transaction_base import TransactionBase
|
from utilities.transaction_base import TransactionBase
|
||||||
|
|
||||||
class DocType(TransactionBase):
|
class DocType(TransactionBase):
|
||||||
def __init__(self, doc, doclist=[]):
|
def __init__(self, doc, doclist=[]):
|
||||||
self.doc = doc
|
self.doc = doc
|
||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
|
|
||||||
#get item details
|
#get item details
|
||||||
#------------------
|
#------------------
|
||||||
def get_item_details(self, item_code):
|
def get_item_details(self, item_code):
|
||||||
item = sql("select item_name,description from `tabItem` where name = '%s'" %(item_code), as_dict=1)
|
item = sql("select item_name,description from `tabItem` where name = '%s'" %(item_code), as_dict=1)
|
||||||
ret = {
|
ret = {
|
||||||
'item_name' : item and item[0]['item_name'] or '',
|
'item_name' : item and item[0]['item_name'] or '',
|
||||||
'description' : item and item[0]['description'] or ''
|
'description' : item and item[0]['description'] or ''
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# fetch details of resp Sales order or customer issue
|
# fetch details of resp Sales order or customer issue
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
def fetch_items(self):
|
def fetch_items(self):
|
||||||
if self.doc.sales_order_no and self.doc.customer_issue_no:
|
if self.doc.sales_order_no and self.doc.customer_issue_no :
|
||||||
msgprint("You can not fetch details of both, Sales Order and Customer Issue, in same Maintenance Visit")
|
msgprint("You can not fetch details of both, Sales Order and Customer Issue, in same Maintenance Visit")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
self.doclist = self.doc.clear_table(self.doclist, 'maintenance_visit_details')
|
self.doclist = self.doc.clear_table(self.doclist, 'maintenance_visit_details')
|
||||||
|
|
||||||
if self.doc.sales_order_no:
|
if self.doc.sales_order_no:
|
||||||
self.doclist = get_obj('DocType Mapper', 'Sales Order-Maintenance Visit').dt_map('Sales Order', 'Maintenance Visit', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Maintenance Visit'],['Sales Order Item', 'Maintenance Visit Purpose']]")
|
self.doclist = get_obj('DocType Mapper', 'Sales Order-Maintenance Visit').dt_map('Sales Order', \
|
||||||
|
'Maintenance Visit', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Maintenance Visit'],\
|
||||||
|
['Sales Order Item', 'Maintenance Visit Purpose']]")
|
||||||
|
elif self.doc.customer_issue_no:
|
||||||
|
self.doclist = get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit').dt_map('Customer Issue', \
|
||||||
|
'Maintenance Visit', self.doc.customer_issue_no, self.doc, self.doclist, "[['Customer Issue', 'Maintenance Visit'],\
|
||||||
|
['Customer Issue', 'Maintenance Visit Purpose']]")
|
||||||
|
elif self.doc.maintenance_schedule:
|
||||||
|
self.doclist = get_obj('DocType Mapper', 'Maintenance Schedule-Maintenance Visit').dt_map('Maintenance Schedule',\
|
||||||
|
'Maintenance Visit', self.doc.maintenance_schedule, self.doc, self.doclist, "[['Maintenance Schedule', \
|
||||||
|
'Maintenance Visit'], ['Maintenance Schedule Item', 'Maintenance Visit Purpose']]")
|
||||||
|
|
||||||
elif self.doc.customer_issue_no:
|
#validate reference value using doctype mapper
|
||||||
self.doclist = get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit').dt_map('Customer Issue', 'Maintenance Visit', self.doc.customer_issue_no, self.doc, self.doclist, "[['Customer Issue', 'Maintenance Visit'],['Customer Issue', 'Maintenance Visit Purpose']]")
|
#-----------------------------------------------------
|
||||||
|
def validate_reference_value(self, check_for):
|
||||||
|
if check_for == 'Sales Order':
|
||||||
|
get_obj('DocType Mapper', 'Sales Order-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||||
|
elif check_for == 'Customer Issue':
|
||||||
|
get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||||
|
|
||||||
#validate reference value using doctype mapper
|
#check if serial no exist in system
|
||||||
#-----------------------------------------------------
|
#--------------------------------------
|
||||||
def validate_reference_value(self, check_for):
|
def validate_serial_no(self):
|
||||||
if check_for == 'Sales Order':
|
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
||||||
get_obj('DocType Mapper', 'Sales Order-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name)
|
if d.serial_no and not sql("select name from `tabSerial No` where name = '%s' and docstatus != 2" % d.serial_no):
|
||||||
elif check_for == 'Customer Issue':
|
msgprint("Serial No: "+ d.serial_no + " not exists in the system")
|
||||||
get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name)
|
raise Exception
|
||||||
|
|
||||||
#check if serial no exist in system
|
|
||||||
#--------------------------------------
|
|
||||||
def validate_serial_no(self):
|
|
||||||
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
|
||||||
if d.serial_no and not sql("select name from `tabSerial No` where name = '%s' and docstatus != 2" % d.serial_no):
|
|
||||||
msgprint("Serial No: "+ d.serial_no + " not exists in the system")
|
|
||||||
raise Exception
|
|
||||||
#elif not d.serial_no and d.item_code:
|
|
||||||
# ser = sql("select has_serial_no from tabItem where name = '%s'" % d.item_code)
|
|
||||||
# ser = ser and ser[0][0] or 'No'
|
|
||||||
# if ser == 'Yes':
|
|
||||||
# msgprint("Serial No is mandatory for item: " + d.item_code)
|
|
||||||
# raise Exception
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not getlist(self.doclist, 'maintenance_visit_details'):
|
if not getlist(self.doclist, 'maintenance_visit_details'):
|
||||||
msgprint("Please enter maintenance details")
|
msgprint("Please enter maintenance details")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
check_for = ''
|
||||||
if d.prevdoc_doctype == 'Sales Order':
|
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
||||||
check_for = 'Sales Order'
|
if d.prevdoc_doctype == 'Sales Order':
|
||||||
elif d.prevdoc_doctype == 'Customer Issue':
|
check_for = 'Sales Order'
|
||||||
check_for = 'Customer Issue'
|
elif d.prevdoc_doctype == 'Customer Issue':
|
||||||
else:
|
check_for = 'Customer Issue'
|
||||||
msgprint("Maintenance Visit must be created either against Sales Order or against Customer Issue")
|
|
||||||
raise Exception
|
|
||||||
|
|
||||||
if check_for:
|
if check_for:
|
||||||
self.validate_reference_value(check_for)
|
self.validate_reference_value(check_for)
|
||||||
|
|
||||||
self.validate_serial_no()
|
self.validate_serial_no()
|
||||||
|
|
||||||
def update_customer_issue(self, flag):
|
def update_customer_issue(self, flag):
|
||||||
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
||||||
if d.prevdoc_docname and d.prevdoc_doctype == 'Customer Issue' :
|
if d.prevdoc_docname and d.prevdoc_doctype == 'Customer Issue' :
|
||||||
if flag==1:
|
if flag==1:
|
||||||
mntc_date = self.doc.mntc_date
|
mntc_date = self.doc.mntc_date
|
||||||
service_person = d.service_person
|
service_person = d.service_person
|
||||||
work_done = d.work_done
|
work_done = d.work_done
|
||||||
if self.doc.completion_status == 'Fully Completed':
|
if self.doc.completion_status == 'Fully Completed':
|
||||||
status = 'Closed'
|
status = 'Closed'
|
||||||
elif self.doc.completion_status == 'Partially Completed':
|
elif self.doc.completion_status == 'Partially Completed':
|
||||||
status = 'Work In Progress'
|
status = 'Work In Progress'
|
||||||
else:
|
else:
|
||||||
nm = sql("select t1.name, t1.mntc_date, t2.service_person, t2.work_done from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.completion_status = 'Partially Completed' and t2.prevdoc_docname = %s and t1.name!=%s and t1.docstatus = 1 order by t1.name desc limit 1", (d.prevdoc_docname, self.doc.name))
|
nm = sql("select t1.name, t1.mntc_date, t2.service_person, t2.work_done from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.completion_status = 'Partially Completed' and t2.prevdoc_docname = %s and t1.name!=%s and t1.docstatus = 1 order by t1.name desc limit 1", (d.prevdoc_docname, self.doc.name))
|
||||||
|
|
||||||
if nm:
|
if nm:
|
||||||
status = 'Work In Progress'
|
status = 'Work In Progress'
|
||||||
mntc_date = nm and nm[0][1] or ''
|
mntc_date = nm and nm[0][1] or ''
|
||||||
service_person = nm and nm[0][2] or ''
|
service_person = nm and nm[0][2] or ''
|
||||||
work_done = nm and nm[0][3] or ''
|
work_done = nm and nm[0][3] or ''
|
||||||
else:
|
else:
|
||||||
status = 'Open'
|
status = 'Open'
|
||||||
mntc_date = ''
|
mntc_date = ''
|
||||||
service_person = ''
|
service_person = ''
|
||||||
work_done = ''
|
work_done = ''
|
||||||
|
|
||||||
sql("update `tabCustomer Issue` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname))
|
sql("update `tabCustomer Issue` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname))
|
||||||
|
|
||||||
# check if last maintenance visit against same sales order/ customer issue
|
|
||||||
#-----------------------------------------------------------------------------------
|
|
||||||
def check_if_last_visit(self):
|
|
||||||
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
|
||||||
if d.prevdoc_docname:
|
|
||||||
check_for_docname = d.prevdoc_docname
|
|
||||||
check_for_doctype = d.prevdoc_doctype
|
|
||||||
|
|
||||||
if check_for_docname:
|
def check_if_last_visit(self):
|
||||||
check = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.name!=%s and t2.prevdoc_docname=%s and t1.docstatus = 1 and (t1.mntc_date > %s or (t1.mntc_date = %s and t1.mntc_time > %s))", (self.doc.name, check_for_docname, self.doc.mntc_date, self.doc.mntc_date, self.doc.mntc_time))
|
"""check if last maintenance visit against same sales order/ customer issue"""
|
||||||
|
for d in getlist(self.doclist, 'maintenance_visit_details'):
|
||||||
|
if d.prevdoc_docname:
|
||||||
|
check_for_docname = d.prevdoc_docname
|
||||||
|
check_for_doctype = d.prevdoc_doctype
|
||||||
|
|
||||||
if check:
|
if check_for_docname:
|
||||||
check_lst = [x[0] for x in check]
|
check = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.name!=%s and t2.prevdoc_docname=%s and t1.docstatus = 1 and (t1.mntc_date > %s or (t1.mntc_date = %s and t1.mntc_time > %s))", (self.doc.name, check_for_docname, self.doc.mntc_date, self.doc.mntc_date, self.doc.mntc_time))
|
||||||
check_lst =','.join(check_lst)
|
|
||||||
msgprint("To cancel this, you need to cancel Maintenance Visit(s) "+cstr(check_lst)+" created after this maintenance visit against same "+check_for_doctype)
|
|
||||||
raise Exception
|
|
||||||
else:
|
|
||||||
self.update_customer_issue(0)
|
|
||||||
|
|
||||||
def on_submit(self):
|
if check:
|
||||||
self.update_customer_issue(1)
|
check_lst = [x[0] for x in check]
|
||||||
set(self.doc, 'status', 'Submitted')
|
check_lst =','.join(check_lst)
|
||||||
|
msgprint("To cancel this, you need to cancel Maintenance Visit(s) "+cstr(check_lst)+" created after this maintenance visit against same "+check_for_doctype)
|
||||||
|
raise Exception
|
||||||
|
else:
|
||||||
|
self.update_customer_issue(0)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_submit(self):
|
||||||
self.check_if_last_visit()
|
self.update_customer_issue(1)
|
||||||
set(self.doc, 'status', 'Cancelled')
|
set(self.doc, 'status', 'Submitted')
|
||||||
|
|
||||||
def on_update(self):
|
def on_cancel(self):
|
||||||
pass
|
self.check_if_last_visit()
|
||||||
|
set(self.doc, 'status', 'Cancelled')
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
# These values are common in all dictionaries
|
# These values are common in all dictionaries
|
||||||
{
|
{
|
||||||
'creation': '2012-03-27 14:36:42',
|
'creation': '2012-06-11 12:10:15',
|
||||||
'docstatus': 0,
|
'docstatus': 0,
|
||||||
'modified': '2012-03-27 14:45:49',
|
'modified': '2012-06-27 12:50:00',
|
||||||
'modified_by': u'Administrator',
|
'modified_by': u'Administrator',
|
||||||
'owner': u'ashwini@webnotestech.com'
|
'owner': u'ashwini@webnotestech.com'
|
||||||
},
|
},
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
'show_in_menu': 0,
|
'show_in_menu': 0,
|
||||||
'subject': u'To %(customer_name)s on %(mntc_date)s',
|
'subject': u'To %(customer_name)s on %(mntc_date)s',
|
||||||
'tag_fields': u'completion_status,maintenance_type',
|
'tag_fields': u'completion_status,maintenance_type',
|
||||||
'version': 95
|
'version': 1
|
||||||
},
|
},
|
||||||
|
|
||||||
# These values are common for all DocField
|
# These values are common for all DocField
|
||||||
@@ -144,38 +144,17 @@
|
|||||||
'permlevel': 0,
|
'permlevel': 0,
|
||||||
'print_hide': 1,
|
'print_hide': 1,
|
||||||
'reqd': 1,
|
'reqd': 1,
|
||||||
'search_index': 1,
|
'search_index': 0,
|
||||||
'trigger': u'Client'
|
'trigger': u'Client'
|
||||||
},
|
},
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'customer_address',
|
|
||||||
'fieldtype': u'Link',
|
|
||||||
'label': u'Customer Address',
|
|
||||||
'options': u'Address',
|
|
||||||
'permlevel': 0,
|
|
||||||
'print_hide': 1
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'contact_person',
|
|
||||||
'fieldtype': u'Link',
|
|
||||||
'label': u'Contact Person',
|
|
||||||
'options': u'Contact',
|
|
||||||
'permlevel': 0,
|
|
||||||
'print_hide': 1
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
'fieldname': u'customer_name',
|
'fieldname': u'customer_name',
|
||||||
'fieldtype': u'Data',
|
'fieldtype': u'Data',
|
||||||
'label': u'Name',
|
'hidden': 1,
|
||||||
|
'label': u'Customer Name',
|
||||||
'permlevel': 1
|
'permlevel': 1
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -184,6 +163,7 @@
|
|||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
'fieldname': u'address_display',
|
'fieldname': u'address_display',
|
||||||
'fieldtype': u'Small Text',
|
'fieldtype': u'Small Text',
|
||||||
|
'hidden': 1,
|
||||||
'label': u'Address',
|
'label': u'Address',
|
||||||
'permlevel': 1
|
'permlevel': 1
|
||||||
},
|
},
|
||||||
@@ -193,6 +173,7 @@
|
|||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
'fieldname': u'contact_display',
|
'fieldname': u'contact_display',
|
||||||
'fieldtype': u'Small Text',
|
'fieldtype': u'Small Text',
|
||||||
|
'hidden': 1,
|
||||||
'label': u'Contact',
|
'label': u'Contact',
|
||||||
'permlevel': 1
|
'permlevel': 1
|
||||||
},
|
},
|
||||||
@@ -202,6 +183,7 @@
|
|||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
'fieldname': u'contact_mobile',
|
'fieldname': u'contact_mobile',
|
||||||
'fieldtype': u'Data',
|
'fieldtype': u'Data',
|
||||||
|
'hidden': 1,
|
||||||
'label': u'Mobile No',
|
'label': u'Mobile No',
|
||||||
'permlevel': 1
|
'permlevel': 1
|
||||||
},
|
},
|
||||||
@@ -211,42 +193,11 @@
|
|||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
'fieldname': u'contact_email',
|
'fieldname': u'contact_email',
|
||||||
'fieldtype': u'Data',
|
'fieldtype': u'Data',
|
||||||
|
'hidden': 1,
|
||||||
'label': u'Contact Email',
|
'label': u'Contact Email',
|
||||||
'permlevel': 1
|
'permlevel': 1
|
||||||
},
|
},
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'company',
|
|
||||||
'fieldtype': u'Select',
|
|
||||||
'in_filter': 1,
|
|
||||||
'label': u'Company',
|
|
||||||
'oldfieldname': u'company',
|
|
||||||
'oldfieldtype': u'Select',
|
|
||||||
'options': u'link:Company',
|
|
||||||
'permlevel': 0,
|
|
||||||
'print_hide': 1,
|
|
||||||
'reqd': 1,
|
|
||||||
'search_index': 0
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'fiscal_year',
|
|
||||||
'fieldtype': u'Select',
|
|
||||||
'in_filter': 1,
|
|
||||||
'label': u'Fiscal Year',
|
|
||||||
'oldfieldname': u'fiscal_year',
|
|
||||||
'oldfieldtype': u'Select',
|
|
||||||
'options': u'link:Fiscal Year',
|
|
||||||
'permlevel': 0,
|
|
||||||
'print_hide': 1,
|
|
||||||
'reqd': 1,
|
|
||||||
'search_index': 0
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
@@ -283,72 +234,6 @@
|
|||||||
'permlevel': 0
|
'permlevel': 0
|
||||||
},
|
},
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'colour': u'White:FFF',
|
|
||||||
'default': u'Draft',
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'status',
|
|
||||||
'fieldtype': u'Data',
|
|
||||||
'label': u'Status',
|
|
||||||
'no_copy': 1,
|
|
||||||
'oldfieldname': u'status',
|
|
||||||
'oldfieldtype': u'Data',
|
|
||||||
'options': u'\nDraft\nCancelled\nSubmitted',
|
|
||||||
'permlevel': 1,
|
|
||||||
'reqd': 1
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'amended_from',
|
|
||||||
'fieldtype': u'Data',
|
|
||||||
'label': u'Amended From',
|
|
||||||
'no_copy': 1,
|
|
||||||
'oldfieldname': u'amended_from',
|
|
||||||
'oldfieldtype': u'Data',
|
|
||||||
'permlevel': 1,
|
|
||||||
'print_hide': 1,
|
|
||||||
'width': u'150px'
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'amendment_date',
|
|
||||||
'fieldtype': u'Date',
|
|
||||||
'label': u'Amendment Date',
|
|
||||||
'no_copy': 1,
|
|
||||||
'oldfieldname': u'amendment_date',
|
|
||||||
'oldfieldtype': u'Date',
|
|
||||||
'permlevel': 0,
|
|
||||||
'print_hide': 1,
|
|
||||||
'width': u'100px'
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'territory',
|
|
||||||
'fieldtype': u'Link',
|
|
||||||
'label': u'Territory',
|
|
||||||
'options': u'Territory',
|
|
||||||
'permlevel': 0,
|
|
||||||
'print_hide': 1
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
|
||||||
{
|
|
||||||
'doctype': u'DocField',
|
|
||||||
'fieldname': u'customer_group',
|
|
||||||
'fieldtype': u'Link',
|
|
||||||
'label': u'Customer Group',
|
|
||||||
'options': u'Customer Group',
|
|
||||||
'permlevel': 0,
|
|
||||||
'print_hide': 1
|
|
||||||
},
|
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
@@ -432,6 +317,17 @@
|
|||||||
'trigger': u'Client'
|
'trigger': u'Client'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'maintenance_schedule',
|
||||||
|
'fieldtype': u'Link',
|
||||||
|
'in_filter': 1,
|
||||||
|
'label': u'Maintenance Schedule',
|
||||||
|
'options': u'Maintenance Schedule',
|
||||||
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
@@ -470,9 +366,9 @@
|
|||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
'fieldname': u'feedback',
|
'fieldname': u'more_info',
|
||||||
'fieldtype': u'Section Break',
|
'fieldtype': u'Section Break',
|
||||||
'label': u'Feedback',
|
'label': u'More Info',
|
||||||
'oldfieldtype': u'Section Break',
|
'oldfieldtype': u'Section Break',
|
||||||
'permlevel': 0
|
'permlevel': 0
|
||||||
},
|
},
|
||||||
@@ -486,5 +382,150 @@
|
|||||||
'oldfieldname': u'customer_feedback',
|
'oldfieldname': u'customer_feedback',
|
||||||
'oldfieldtype': u'Small Text',
|
'oldfieldtype': u'Small Text',
|
||||||
'permlevel': 0
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'col_break3',
|
||||||
|
'fieldtype': u'Column Break',
|
||||||
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'colour': u'White:FFF',
|
||||||
|
'default': u'Draft',
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'status',
|
||||||
|
'fieldtype': u'Data',
|
||||||
|
'label': u'Status',
|
||||||
|
'no_copy': 1,
|
||||||
|
'oldfieldname': u'status',
|
||||||
|
'oldfieldtype': u'Data',
|
||||||
|
'options': u'\nDraft\nCancelled\nSubmitted',
|
||||||
|
'permlevel': 1,
|
||||||
|
'reqd': 1
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'amended_from',
|
||||||
|
'fieldtype': u'Data',
|
||||||
|
'label': u'Amended From',
|
||||||
|
'no_copy': 1,
|
||||||
|
'oldfieldname': u'amended_from',
|
||||||
|
'oldfieldtype': u'Data',
|
||||||
|
'permlevel': 1,
|
||||||
|
'print_hide': 1,
|
||||||
|
'width': u'150px'
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'amendment_date',
|
||||||
|
'fieldtype': u'Date',
|
||||||
|
'label': u'Amendment Date',
|
||||||
|
'no_copy': 1,
|
||||||
|
'oldfieldname': u'amendment_date',
|
||||||
|
'oldfieldtype': u'Date',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1,
|
||||||
|
'width': u'100px'
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'company',
|
||||||
|
'fieldtype': u'Select',
|
||||||
|
'in_filter': 1,
|
||||||
|
'label': u'Company',
|
||||||
|
'oldfieldname': u'company',
|
||||||
|
'oldfieldtype': u'Select',
|
||||||
|
'options': u'link:Company',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1,
|
||||||
|
'reqd': 1,
|
||||||
|
'search_index': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'fiscal_year',
|
||||||
|
'fieldtype': u'Select',
|
||||||
|
'in_filter': 1,
|
||||||
|
'label': u'Fiscal Year',
|
||||||
|
'oldfieldname': u'fiscal_year',
|
||||||
|
'oldfieldtype': u'Select',
|
||||||
|
'options': u'link:Fiscal Year',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1,
|
||||||
|
'reqd': 1,
|
||||||
|
'search_index': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'contact_info_section',
|
||||||
|
'fieldtype': u'Section Break',
|
||||||
|
'label': u'Contact Info',
|
||||||
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'customer_address',
|
||||||
|
'fieldtype': u'Link',
|
||||||
|
'label': u'Customer Address',
|
||||||
|
'options': u'Address',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'contact_person',
|
||||||
|
'fieldtype': u'Link',
|
||||||
|
'label': u'Contact Person',
|
||||||
|
'options': u'Contact',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'col_break4',
|
||||||
|
'fieldtype': u'Column Break',
|
||||||
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'territory',
|
||||||
|
'fieldtype': u'Link',
|
||||||
|
'label': u'Territory',
|
||||||
|
'options': u'Territory',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'customer_group',
|
||||||
|
'fieldtype': u'Link',
|
||||||
|
'label': u'Customer Group',
|
||||||
|
'options': u'Customer Group',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Reference in New Issue
Block a user