Merge branch 'dev' of github.com:webnotes/erpnext into dev
This commit is contained in:
commit
8cbbab2e75
@ -204,9 +204,6 @@ class DocType:
|
|||||||
if sql("select name from `tabFiscal Year` where year_start_date < %s", self.doc.year_start_date) and not self.doc.past_year:
|
if sql("select name from `tabFiscal Year` where year_start_date < %s", self.doc.year_start_date) and not self.doc.past_year:
|
||||||
msgprint("Please enter Past Year", raise_exception=1)
|
msgprint("Please enter Past Year", raise_exception=1)
|
||||||
|
|
||||||
if not self.doc.is_fiscal_year_closed:
|
|
||||||
self.doc.is_fiscal_year_closed = 'No'
|
|
||||||
|
|
||||||
|
|
||||||
# on update
|
# on update
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
|
|||||||
@ -40,18 +40,12 @@ class DocType(TransactionBase):
|
|||||||
self.fname = 'entries'
|
self.fname = 'entries'
|
||||||
|
|
||||||
|
|
||||||
# Autoname
|
|
||||||
# ---------
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
self.doc.name = make_autoname(self.doc.naming_series+ '.#####')
|
self.doc.name = make_autoname(self.doc.naming_series+ '.#####')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ********************************* Trigger Functions ******************************
|
|
||||||
|
|
||||||
#Set retail related fields from pos settings
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
def set_pos_fields(self):
|
def set_pos_fields(self):
|
||||||
|
"""Set retail related fields from pos settings"""
|
||||||
pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
|
pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
|
||||||
if not pos:
|
if not pos:
|
||||||
pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % (self.doc.company), as_dict=1)
|
pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % (self.doc.company), as_dict=1)
|
||||||
@ -79,9 +73,8 @@ class DocType(TransactionBase):
|
|||||||
if self.doc.charge: self.get_other_charges()
|
if self.doc.charge: self.get_other_charges()
|
||||||
|
|
||||||
|
|
||||||
# Set default values related to pos for previously created sales invoice.
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
def set_pos_item_values(self):
|
def set_pos_item_values(self):
|
||||||
|
"""Set default values related to pos for previously created sales invoice."""
|
||||||
if cint(self.doc.is_pos) ==1:
|
if cint(self.doc.is_pos) ==1:
|
||||||
dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
|
dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
|
||||||
if not dtl:
|
if not dtl:
|
||||||
@ -94,10 +87,8 @@ class DocType(TransactionBase):
|
|||||||
d.warehouse = item and item[0]['default_warehouse'] or dtl and dtl[0]['warehouse'] or d.warehouse
|
d.warehouse = item and item[0]['default_warehouse'] or dtl and dtl[0]['warehouse'] or d.warehouse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Get Account Head to which amount needs to be Debited based on Customer
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
def get_customer_account(self):
|
def get_customer_account(self):
|
||||||
|
"""Get Account Head to which amount needs to be Debited based on Customer"""
|
||||||
if not self.doc.company:
|
if not self.doc.company:
|
||||||
msgprint("Please select company first and re-select the customer after doing so", raise_exception=1)
|
msgprint("Please select company first and re-select the customer after doing so", raise_exception=1)
|
||||||
|
|
||||||
@ -115,10 +106,8 @@ class DocType(TransactionBase):
|
|||||||
return acc_head and {'debit_to' : acc_head} or {}
|
return acc_head and {'debit_to' : acc_head} or {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Set Due Date = Posting Date + Credit Days
|
|
||||||
# -----------------------------------------
|
|
||||||
def get_cust_and_due_date(self):
|
def get_cust_and_due_date(self):
|
||||||
|
"""Set Due Date = Posting Date + Credit Days"""
|
||||||
credit_days = 0
|
credit_days = 0
|
||||||
if self.doc.debit_to:
|
if self.doc.debit_to:
|
||||||
credit_days = webnotes.conn.sql("select credit_days from `tabAccount` where name='%s' and docstatus != 2" % self.doc.debit_to)
|
credit_days = webnotes.conn.sql("select credit_days from `tabAccount` where name='%s' and docstatus != 2" % self.doc.debit_to)
|
||||||
@ -134,9 +123,8 @@ class DocType(TransactionBase):
|
|||||||
self.doc.customer = webnotes.conn.get_value('Account',self.doc.debit_to,'master_name')
|
self.doc.customer = webnotes.conn.get_value('Account',self.doc.debit_to,'master_name')
|
||||||
|
|
||||||
|
|
||||||
# Pull Details of Delivery Note or Sales Order Selected
|
|
||||||
# ------------------------------------------------------
|
|
||||||
def pull_details(self):
|
def pull_details(self):
|
||||||
|
"""Pull Details of Delivery Note or Sales Order Selected"""
|
||||||
# Delivery Note
|
# Delivery Note
|
||||||
if self.doc.delivery_note_main:
|
if self.doc.delivery_note_main:
|
||||||
self.validate_prev_docname('delivery note')
|
self.validate_prev_docname('delivery note')
|
||||||
@ -153,14 +141,14 @@ class DocType(TransactionBase):
|
|||||||
ret = self.get_debit_to()
|
ret = self.get_debit_to()
|
||||||
self.doc.debit_to = ret.get('debit_to')
|
self.doc.debit_to = ret.get('debit_to')
|
||||||
|
|
||||||
# onload pull income account
|
|
||||||
# --------------------------
|
|
||||||
def load_default_accounts(self):
|
def load_default_accounts(self):
|
||||||
"""
|
"""
|
||||||
Loads default accounts from items, customer when called from mapper
|
Loads default accounts from items, customer when called from mapper
|
||||||
"""
|
"""
|
||||||
self.get_income_account('entries')
|
self.get_income_account('entries')
|
||||||
|
|
||||||
|
|
||||||
def get_income_account(self,doctype):
|
def get_income_account(self,doctype):
|
||||||
for d in getlist(self.doclist, doctype):
|
for d in getlist(self.doclist, doctype):
|
||||||
if d.item_code:
|
if d.item_code:
|
||||||
@ -168,8 +156,7 @@ class DocType(TransactionBase):
|
|||||||
d.income_account = item and item[0]['default_income_account'] or ''
|
d.income_account = item and item[0]['default_income_account'] or ''
|
||||||
d.cost_center = item and item[0]['default_sales_cost_center'] or ''
|
d.cost_center = item and item[0]['default_sales_cost_center'] or ''
|
||||||
|
|
||||||
# Item Details
|
|
||||||
# -------------
|
|
||||||
def get_item_details(self, args=None):
|
def get_item_details(self, args=None):
|
||||||
import json
|
import json
|
||||||
args = args and json.loads(args) or {}
|
args = args and json.loads(args) or {}
|
||||||
@ -215,61 +202,49 @@ class DocType(TransactionBase):
|
|||||||
return get_obj('Sales Common').get_barcode_details(barcode)
|
return get_obj('Sales Common').get_barcode_details(barcode)
|
||||||
|
|
||||||
|
|
||||||
# Fetch ref rate from item master as per selected price list
|
|
||||||
def get_adj_percent(self, arg=''):
|
def get_adj_percent(self, arg=''):
|
||||||
|
"""Fetch ref rate from item master as per selected price list"""
|
||||||
get_obj('Sales Common').get_adj_percent(self)
|
get_obj('Sales Common').get_adj_percent(self)
|
||||||
|
|
||||||
|
|
||||||
# Get tax rate if account type is tax
|
|
||||||
# ------------------------------------
|
|
||||||
def get_rate(self,arg):
|
def get_rate(self,arg):
|
||||||
|
"""Get tax rate if account type is tax"""
|
||||||
get_obj('Sales Common').get_rate(arg)
|
get_obj('Sales Common').get_rate(arg)
|
||||||
|
|
||||||
|
|
||||||
# Get Commission rate of Sales Partner
|
|
||||||
# -------------------------------------
|
|
||||||
def get_comm_rate(self, sales_partner):
|
def get_comm_rate(self, sales_partner):
|
||||||
|
"""Get Commission rate of Sales Partner"""
|
||||||
return get_obj('Sales Common').get_comm_rate(sales_partner, self)
|
return get_obj('Sales Common').get_comm_rate(sales_partner, self)
|
||||||
|
|
||||||
|
|
||||||
# GET TERMS & CONDITIONS
|
|
||||||
# -------------------------------------
|
|
||||||
def get_tc_details(self):
|
def get_tc_details(self):
|
||||||
return get_obj('Sales Common').get_tc_details(self)
|
return get_obj('Sales Common').get_tc_details(self)
|
||||||
|
|
||||||
# Load Default Charges
|
|
||||||
# ----------------------------------------------------------
|
|
||||||
def load_default_taxes(self):
|
def load_default_taxes(self):
|
||||||
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
||||||
|
|
||||||
# Get Sales Taxes and Charges Master Details
|
|
||||||
# --------------------------
|
|
||||||
def get_other_charges(self):
|
def get_other_charges(self):
|
||||||
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
||||||
|
|
||||||
# Get Advances
|
|
||||||
# -------------
|
|
||||||
def get_advances(self):
|
def get_advances(self):
|
||||||
self.doclist = get_obj('GL Control').get_advances(self, self.doc.debit_to, 'Sales Invoice Advance', 'advance_adjustment_details', 'credit')
|
self.doclist = get_obj('GL Control').get_advances(self, self.doc.debit_to, 'Sales Invoice Advance', 'advance_adjustment_details', 'credit')
|
||||||
|
|
||||||
#pull project customer
|
|
||||||
#-------------------------
|
|
||||||
def pull_project_customer(self):
|
def pull_project_customer(self):
|
||||||
res = webnotes.conn.sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
|
res = webnotes.conn.sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
|
||||||
if res:
|
if res:
|
||||||
get_obj('DocType Mapper', 'Project-Sales Invoice').dt_map('Project', 'Sales Invoice', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Invoice']]")
|
get_obj('DocType Mapper', 'Project-Sales Invoice').dt_map('Project', 'Sales Invoice', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Invoice']]")
|
||||||
|
|
||||||
# ********************************** Server Utility Functions ******************************
|
|
||||||
|
|
||||||
# Get Company Abbr.
|
|
||||||
# ------------------
|
|
||||||
def get_company_abbr(self):
|
def get_company_abbr(self):
|
||||||
return webnotes.conn.sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
|
return webnotes.conn.sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
|
||||||
|
|
||||||
|
|
||||||
# Check whether sales order / delivery note items already pulled
|
|
||||||
#----------------------------------------------------------------
|
|
||||||
def validate_prev_docname(self,doctype):
|
def validate_prev_docname(self,doctype):
|
||||||
|
"""Check whether sales order / delivery note items already pulled"""
|
||||||
for d in getlist(self.doclist, 'entries'):
|
for d in getlist(self.doclist, 'entries'):
|
||||||
if doctype == 'delivery note' and self.doc.delivery_note_main == d.delivery_note:
|
if doctype == 'delivery note' and self.doc.delivery_note_main == d.delivery_note:
|
||||||
msgprint(cstr(self.doc.delivery_note_main) + " delivery note details have already been pulled.")
|
msgprint(cstr(self.doc.delivery_note_main) + " delivery note details have already been pulled.")
|
||||||
@ -279,7 +254,6 @@ class DocType(TransactionBase):
|
|||||||
raise Exception , "Validation Error. Sales order details have already been pulled."
|
raise Exception , "Validation Error. Sales order details have already been pulled."
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------
|
|
||||||
def update_against_document_in_jv(self):
|
def update_against_document_in_jv(self):
|
||||||
"""
|
"""
|
||||||
Links invoice and advance voucher:
|
Links invoice and advance voucher:
|
||||||
@ -308,11 +282,8 @@ class DocType(TransactionBase):
|
|||||||
get_obj('GL Control').reconcile_against_document(lst)
|
get_obj('GL Control').reconcile_against_document(lst)
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------
|
|
||||||
def validate_customer(self):
|
def validate_customer(self):
|
||||||
"""
|
""" Validate customer name with SO and DN"""
|
||||||
Validate customer name with SO and DN
|
|
||||||
"""
|
|
||||||
for d in getlist(self.doclist,'entries'):
|
for d in getlist(self.doclist,'entries'):
|
||||||
dt = d.delivery_note and 'Delivery Note' or d.sales_order and 'Sales Order' or ''
|
dt = d.delivery_note and 'Delivery Note' or d.sales_order and 'Sales Order' or ''
|
||||||
if dt:
|
if dt:
|
||||||
@ -322,9 +293,8 @@ class DocType(TransactionBase):
|
|||||||
msgprint("Customer %s does not match with customer of %s: %s." %(self.doc.customer, dt, dt_no), raise_exception=1)
|
msgprint("Customer %s does not match with customer of %s: %s." %(self.doc.customer, dt, dt_no), raise_exception=1)
|
||||||
|
|
||||||
|
|
||||||
# Validates Debit To Account and Customer Matches
|
def validate_customer_account(self):
|
||||||
# ------------------------------------------------
|
"""Validates Debit To Account and Customer Matches"""
|
||||||
def validate_debit_to_acc(self):
|
|
||||||
if self.doc.customer and self.doc.debit_to and not cint(self.doc.is_pos):
|
if self.doc.customer and self.doc.debit_to and not cint(self.doc.is_pos):
|
||||||
acc_head = webnotes.conn.sql("select master_name from `tabAccount` where name = %s and docstatus != 2", self.doc.debit_to)
|
acc_head = webnotes.conn.sql("select master_name from `tabAccount` where name = %s and docstatus != 2", self.doc.debit_to)
|
||||||
|
|
||||||
@ -334,11 +304,6 @@ class DocType(TransactionBase):
|
|||||||
and Master Name in account master." %(self.doc.debit_to, self.doc.customer,self.doc.company), raise_exception=1)
|
and Master Name in account master." %(self.doc.debit_to, self.doc.customer,self.doc.company), raise_exception=1)
|
||||||
|
|
||||||
|
|
||||||
# Validate Debit To Account
|
|
||||||
# 1. Account Exists
|
|
||||||
# 2. Is a Debit Account
|
|
||||||
# 3. Is a PL Account
|
|
||||||
# ---------------------------
|
|
||||||
def validate_debit_acc(self):
|
def validate_debit_acc(self):
|
||||||
acc = webnotes.conn.sql("select debit_or_credit, is_pl_account from tabAccount where name = '%s' and docstatus != 2" % self.doc.debit_to)
|
acc = webnotes.conn.sql("select debit_or_credit, is_pl_account from tabAccount where name = '%s' and docstatus != 2" % self.doc.debit_to)
|
||||||
if not acc:
|
if not acc:
|
||||||
@ -352,9 +317,8 @@ class DocType(TransactionBase):
|
|||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
|
||||||
# Validate Fixed Asset Account and whether Income Account Entered Exists
|
|
||||||
# -----------------------------------------------------------------------
|
|
||||||
def validate_fixed_asset_account(self):
|
def validate_fixed_asset_account(self):
|
||||||
|
"""Validate Fixed Asset Account and whether Income Account Entered Exists"""
|
||||||
for d in getlist(self.doclist,'entries'):
|
for d in getlist(self.doclist,'entries'):
|
||||||
item = webnotes.conn.sql("select name,is_asset_item,is_sales_item from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())"% d.item_code)
|
item = webnotes.conn.sql("select name,is_asset_item,is_sales_item from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())"% d.item_code)
|
||||||
acc = webnotes.conn.sql("select account_type from `tabAccount` where name = '%s' and docstatus != 2" % d.income_account)
|
acc = webnotes.conn.sql("select account_type from `tabAccount` where name = '%s' and docstatus != 2" % d.income_account)
|
||||||
@ -366,22 +330,16 @@ class DocType(TransactionBase):
|
|||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Set totals in words
|
|
||||||
#--------------------
|
|
||||||
def set_in_words(self):
|
def set_in_words(self):
|
||||||
dcc = TransactionBase().get_company_currency(self.doc.company)
|
dcc = TransactionBase().get_company_currency(self.doc.company)
|
||||||
self.doc.in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.rounded_total)
|
self.doc.in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.rounded_total)
|
||||||
self.doc.in_words_export = get_obj('Sales Common').get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
|
self.doc.in_words_export = get_obj('Sales Common').get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
|
||||||
|
|
||||||
# Clear Advances
|
|
||||||
# --------------
|
|
||||||
def clear_advances(self):
|
def clear_advances(self):
|
||||||
get_obj('GL Control').clear_advances(self, 'Sales Invoice Advance','advance_adjustment_details')
|
get_obj('GL Control').clear_advances(self, 'Sales Invoice Advance','advance_adjustment_details')
|
||||||
|
|
||||||
|
|
||||||
# set aging date
|
|
||||||
#-------------------
|
|
||||||
def set_aging_date(self):
|
def set_aging_date(self):
|
||||||
if self.doc.is_opening != 'Yes':
|
if self.doc.is_opening != 'Yes':
|
||||||
self.doc.aging_date = self.doc.posting_date
|
self.doc.aging_date = self.doc.posting_date
|
||||||
@ -390,20 +348,21 @@ class DocType(TransactionBase):
|
|||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
|
||||||
# Set against account for debit to account
|
|
||||||
#------------------------------------------
|
|
||||||
def set_against_income_account(self):
|
def set_against_income_account(self):
|
||||||
|
"""Set against account for debit to account"""
|
||||||
against_acc = []
|
against_acc = []
|
||||||
for d in getlist(self.doclist, 'entries'):
|
for d in getlist(self.doclist, 'entries'):
|
||||||
if d.income_account not in against_acc:
|
if d.income_account not in against_acc:
|
||||||
against_acc.append(d.income_account)
|
against_acc.append(d.income_account)
|
||||||
self.doc.against_income_account = ','.join(against_acc)
|
self.doc.against_income_account = ','.join(against_acc)
|
||||||
|
|
||||||
|
|
||||||
def add_remarks(self):
|
def add_remarks(self):
|
||||||
if not self.doc.remarks: self.doc.remarks = 'No Remarks'
|
if not self.doc.remarks: self.doc.remarks = 'No Remarks'
|
||||||
|
|
||||||
#check in manage account if sales order / delivery note required or not.
|
|
||||||
def so_dn_required(self):
|
def so_dn_required(self):
|
||||||
|
"""check in manage account if sales order / delivery note required or not."""
|
||||||
dict = {'Sales Order':'so_required','Delivery Note':'dn_required'}
|
dict = {'Sales Order':'so_required','Delivery Note':'dn_required'}
|
||||||
for i in dict:
|
for i in dict:
|
||||||
res = webnotes.conn.sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = '%s'"%dict[i])
|
res = webnotes.conn.sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = '%s'"%dict[i])
|
||||||
@ -413,9 +372,9 @@ class DocType(TransactionBase):
|
|||||||
msgprint("%s No. required against item %s"%(i,d.item_code))
|
msgprint("%s No. required against item %s"%(i,d.item_code))
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
#check for does customer belong to same project as entered..
|
|
||||||
#-------------------------------------------------------------------------------------------------
|
|
||||||
def validate_proj_cust(self):
|
def validate_proj_cust(self):
|
||||||
|
"""check for does customer belong to same project as entered.."""
|
||||||
if self.doc.project_name and self.doc.customer:
|
if self.doc.project_name and self.doc.customer:
|
||||||
res = webnotes.conn.sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
|
res = webnotes.conn.sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
|
||||||
if not res:
|
if not res:
|
||||||
@ -431,20 +390,13 @@ class DocType(TransactionBase):
|
|||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
|
||||||
# ********* UPDATE CURRENT STOCK *****************************
|
|
||||||
def update_current_stock(self):
|
|
||||||
for d in getlist(self.doclist, 'entries'):
|
|
||||||
bin = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
|
|
||||||
d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
|
|
||||||
|
|
||||||
def validate_item_code(self):
|
def validate_item_code(self):
|
||||||
for d in getlist(self.doclist, 'entries'):
|
for d in getlist(self.doclist, 'entries'):
|
||||||
if not d.item_code:
|
if not d.item_code:
|
||||||
msgprint("Please enter Item Code at line no : %s to update stock for POS or remove check from Update Stock in Basic Info Tab." % (d.idx))
|
msgprint("Please enter Item Code at line no : %s to update stock for POS or remove check from Update Stock in Basic Info Tab." % (d.idx))
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
# Validate Write Off Account
|
|
||||||
# -------------------------------
|
|
||||||
def validate_write_off_account(self):
|
def validate_write_off_account(self):
|
||||||
if flt(self.doc.write_off_amount) and not self.doc.write_off_account:
|
if flt(self.doc.write_off_amount) and not self.doc.write_off_account:
|
||||||
msgprint("Please enter Write Off Account", raise_exception=1)
|
msgprint("Please enter Write Off Account", raise_exception=1)
|
||||||
@ -458,11 +410,21 @@ class DocType(TransactionBase):
|
|||||||
|
|
||||||
webnotes.conn.set(self.doc, 'c_form_no', '')
|
webnotes.conn.set(self.doc, 'c_form_no', '')
|
||||||
|
|
||||||
# VALIDATE
|
|
||||||
# ====================================================================================
|
def update_current_stock(self):
|
||||||
|
for d in getlist(self.doclist, 'entries'):
|
||||||
|
if d.item_code and d.warehouse:
|
||||||
|
bin = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
|
||||||
|
d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
|
||||||
|
|
||||||
|
for d in getlist(self.doclist, 'packing_details'):
|
||||||
|
bin = sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
|
||||||
|
d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
|
||||||
|
d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
|
||||||
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.so_dn_required()
|
self.so_dn_required()
|
||||||
#self.dn_required()
|
|
||||||
self.validate_proj_cust()
|
self.validate_proj_cust()
|
||||||
sales_com_obj = get_obj('Sales Common')
|
sales_com_obj = get_obj('Sales Common')
|
||||||
sales_com_obj.check_stop_sales_order(self)
|
sales_com_obj.check_stop_sales_order(self)
|
||||||
@ -472,7 +434,7 @@ class DocType(TransactionBase):
|
|||||||
sales_com_obj.get_allocated_sum(self) # this is to verify that the allocated % of sales persons is 100%
|
sales_com_obj.get_allocated_sum(self) # this is to verify that the allocated % of sales persons is 100%
|
||||||
sales_com_obj.validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
|
sales_com_obj.validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
|
||||||
self.validate_customer()
|
self.validate_customer()
|
||||||
self.validate_debit_to_acc()
|
self.validate_customer_account()
|
||||||
self.validate_debit_acc()
|
self.validate_debit_acc()
|
||||||
self.validate_fixed_asset_account()
|
self.validate_fixed_asset_account()
|
||||||
self.add_remarks()
|
self.add_remarks()
|
||||||
@ -480,7 +442,9 @@ class DocType(TransactionBase):
|
|||||||
self.validate_pos()
|
self.validate_pos()
|
||||||
self.validate_write_off_account()
|
self.validate_write_off_account()
|
||||||
if cint(self.doc.update_stock):
|
if cint(self.doc.update_stock):
|
||||||
get_obj('Stock Ledger').validate_serial_no(self, 'entries')
|
sl = get_obj('Stock Ledger')
|
||||||
|
sl.validate_serial_no(self, 'entries')
|
||||||
|
sl.validate_serial_no(self, 'packing_details')
|
||||||
self.validate_item_code()
|
self.validate_item_code()
|
||||||
self.update_current_stock()
|
self.update_current_stock()
|
||||||
self.set_in_words()
|
self.set_in_words()
|
||||||
@ -488,14 +452,62 @@ class DocType(TransactionBase):
|
|||||||
self.doc.is_opening = 'No'
|
self.doc.is_opening = 'No'
|
||||||
self.set_aging_date()
|
self.set_aging_date()
|
||||||
self.clear_advances()
|
self.clear_advances()
|
||||||
# Set against account
|
|
||||||
self.set_against_income_account()
|
self.set_against_income_account()
|
||||||
self.validate_c_form()
|
self.validate_c_form()
|
||||||
|
|
||||||
|
|
||||||
# *************************************************** ON SUBMIT **********************************************
|
def get_warehouse(self):
|
||||||
# Check Ref Document's docstatus
|
w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company))
|
||||||
# -------------------------------
|
w = w and w[0][0] or ''
|
||||||
|
if not w:
|
||||||
|
ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
|
||||||
|
if not ps:
|
||||||
|
msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.")
|
||||||
|
raise Exception
|
||||||
|
elif not ps[0][1]:
|
||||||
|
msgprint("Please enter warehouse in POS Setting")
|
||||||
|
else:
|
||||||
|
w = ps[0][1]
|
||||||
|
return w
|
||||||
|
|
||||||
|
|
||||||
|
def make_packing_list(self):
|
||||||
|
get_obj('Sales Common').make_packing_list(self,'entries')
|
||||||
|
sl = get_obj('Stock Ledger')
|
||||||
|
sl.scrub_serial_nos(self)
|
||||||
|
sl.scrub_serial_nos(self, 'packing_details')
|
||||||
|
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
# Set default warehouse from pos setting
|
||||||
|
if cint(self.doc.is_pos) == 1:
|
||||||
|
if cint(self.doc.update_stock) == 1:
|
||||||
|
w = self.get_warehouse()
|
||||||
|
if w:
|
||||||
|
for d in getlist(self.doclist, 'entries'):
|
||||||
|
if not d.warehouse:
|
||||||
|
d.warehouse = cstr(w)
|
||||||
|
|
||||||
|
self.make_packing_list()
|
||||||
|
else:
|
||||||
|
self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
|
||||||
|
|
||||||
|
if flt(self.doc.paid_amount) == 0:
|
||||||
|
if self.doc.cash_bank_account:
|
||||||
|
webnotes.conn.set(self.doc, 'paid_amount',
|
||||||
|
(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
|
||||||
|
else:
|
||||||
|
# show message that the amount is not paid
|
||||||
|
webnotes.conn.set(self.doc,'paid_amount',0)
|
||||||
|
webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
|
||||||
|
webnotes.conn.set(self.doc,'paid_amount',0)
|
||||||
|
|
||||||
|
webnotes.conn.set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
|
||||||
|
|
||||||
|
|
||||||
def check_prev_docstatus(self):
|
def check_prev_docstatus(self):
|
||||||
for d in getlist(self.doclist,'entries'):
|
for d in getlist(self.doclist,'entries'):
|
||||||
if d.sales_order:
|
if d.sales_order:
|
||||||
@ -511,56 +523,45 @@ class DocType(TransactionBase):
|
|||||||
raise Exception , "Validation Error."
|
raise Exception , "Validation Error."
|
||||||
|
|
||||||
|
|
||||||
#Set Actual Qty based on item code and warehouse
|
|
||||||
#------------------------------------------------------
|
|
||||||
def set_actual_qty(self):
|
|
||||||
for d in getlist(self.doclist, 'entries'):
|
|
||||||
if d.item_code and d.warehouse:
|
|
||||||
actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code, d.warehouse))
|
|
||||||
d.actual_qty = actual_qty and flt(actual_qty[0][0]) or 0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ********************** 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):
|
||||||
st_uom = webnotes.conn.sql("select stock_uom from `tabItem` where name = '%s'"%d.item_code)
|
st_uom = webnotes.conn.sql("select stock_uom from `tabItem` where name = '%s'"%d['item_code'])
|
||||||
self.values.append({
|
self.values.append({
|
||||||
'item_code' : d.item_code,
|
'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' : 'Sales Invoice',
|
'voucher_type' : 'Sales Invoice',
|
||||||
'voucher_no' : cstr(self.doc.name),
|
'voucher_no' : cstr(self.doc.name),
|
||||||
'voucher_detail_no' : cstr(d.name),
|
'voucher_detail_no' : cstr(d['name']),
|
||||||
'actual_qty' : qty,
|
'actual_qty' : qty,
|
||||||
'stock_uom' : st_uom and st_uom[0][0] or '',
|
'stock_uom' : st_uom and st_uom[0][0] or '',
|
||||||
'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' : cstr(d.batch_no),
|
'batch_no' : cstr(d['batch_no']),
|
||||||
'serial_no' : d.serial_no
|
'serial_no' : d['serial_no']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
# UPDATE STOCK LEDGER
|
def update_stock_ledger(self, update_stock):
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
def update_stock_ledger(self, update_stock, clear = 0):
|
|
||||||
self.values = []
|
self.values = []
|
||||||
for d in getlist(self.doclist, 'entries'):
|
items = get_obj('Sales Common').get_item_list(self)
|
||||||
stock_item = webnotes.conn.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
|
for d in items:
|
||||||
|
stock_item = webnotes.conn.sql("SELECT is_stock_item, is_sample_item \
|
||||||
|
FROM tabItem where name = '%s'"%(d['item_code']), as_dict = 1)
|
||||||
if stock_item[0]['is_stock_item'] == "Yes":
|
if stock_item[0]['is_stock_item'] == "Yes":
|
||||||
|
if not d['warehouse']:
|
||||||
|
msgprint("Message: Please enter Warehouse for item %s as it is stock item." \
|
||||||
|
% d['item_code'], raise_exception=1)
|
||||||
|
|
||||||
# Reduce actual qty from warehouse
|
# Reduce actual qty from warehouse
|
||||||
self.make_sl_entry( d, d.warehouse, - flt(d.qty) , 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, self.doc.amended_from and 'Yes' or 'No')
|
|
||||||
|
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
|
||||||
|
|
||||||
|
|
||||||
#-------------------POS Stock Updatation Part----------------------------------------------
|
|
||||||
def pos_update_stock(self):
|
|
||||||
self.update_stock_ledger(update_stock = 1)
|
|
||||||
|
|
||||||
# ********** Get Actual Qty of item in warehouse selected *************
|
|
||||||
def get_actual_qty(self,args):
|
def get_actual_qty(self,args):
|
||||||
args = eval(args)
|
args = eval(args)
|
||||||
actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
|
actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
|
||||||
@ -569,23 +570,39 @@ class DocType(TransactionBase):
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# Make GL Entries
|
|
||||||
# -------------------------
|
|
||||||
def make_gl_entries(self, is_cancel=0):
|
def make_gl_entries(self, is_cancel=0):
|
||||||
mapper = self.doc.is_pos and self.doc.write_off_account and 'POS with write off' or self.doc.is_pos and not self.doc.write_off_account and 'POS' or ''
|
mapper = self.doc.is_pos and self.doc.write_off_account and 'POS with write off' or self.doc.is_pos and not self.doc.write_off_account and 'POS' or ''
|
||||||
update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
|
update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
|
||||||
get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist,cancel = is_cancel, use_mapper = mapper, update_outstanding = update_outstanding, merge_entries = cint(self.doc.is_pos) != 1 and 1 or 0)
|
get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist,cancel = is_cancel, use_mapper = mapper, update_outstanding = update_outstanding, merge_entries = cint(self.doc.is_pos) != 1 and 1 or 0)
|
||||||
|
|
||||||
|
|
||||||
# On Submit
|
def update_c_form(self):
|
||||||
# ---------
|
"""Update amended id in C-form"""
|
||||||
|
if self.doc.c_form_no and self.doc.amended_from:
|
||||||
|
webnotes.conn.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
|
||||||
|
invoice_date = %s, territory = %s, net_total = %s,
|
||||||
|
grand_total = %s where invoice_no = %s and parent = %s""", (self.doc.name, self.doc.amended_from, self.doc.c_form_no))
|
||||||
|
|
||||||
|
|
||||||
|
def check_next_docstatus(self):
|
||||||
|
submit_jv = webnotes.conn.sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_invoice = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||||
|
if submit_jv:
|
||||||
|
msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.")
|
||||||
|
raise Exception, "Validation Error."
|
||||||
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
if cint(self.doc.is_pos) == 1:
|
if cint(self.doc.is_pos) == 1:
|
||||||
if cint(self.doc.update_stock) == 1:
|
if cint(self.doc.update_stock) == 1:
|
||||||
sl_obj = get_obj("Stock Ledger")
|
sl_obj = get_obj("Stock Ledger")
|
||||||
sl_obj.validate_serial_no_warehouse(self, 'entries')
|
sl_obj.validate_serial_no_warehouse(self, 'entries')
|
||||||
|
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
|
||||||
|
|
||||||
sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
|
sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
|
||||||
self.pos_update_stock()
|
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
|
||||||
|
|
||||||
|
self.update_stock_ledger(update_stock=1)
|
||||||
else:
|
else:
|
||||||
self.check_prev_docstatus()
|
self.check_prev_docstatus()
|
||||||
get_obj("Sales Common").update_prevdoc_detail(1,self)
|
get_obj("Sales Common").update_prevdoc_detail(1,self)
|
||||||
@ -603,31 +620,13 @@ class DocType(TransactionBase):
|
|||||||
self.update_c_form()
|
self.update_c_form()
|
||||||
|
|
||||||
|
|
||||||
def update_c_form(self):
|
|
||||||
"""Update amended id in C-form"""
|
|
||||||
if self.doc.c_form_no and self.doc.amended_from:
|
|
||||||
webnotes.conn.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
|
|
||||||
invoice_date = %s, territory = %s, net_total = %s,
|
|
||||||
grand_total = %s where invoice_no = %s and parent = %s""", (self.doc.name, self.doc.amended_from, self.doc.c_form_no))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# *************************************************** ON CANCEL **********************************************
|
|
||||||
# Check Next Document's docstatus
|
|
||||||
# --------------------------------
|
|
||||||
def check_next_docstatus(self):
|
|
||||||
submit_jv = webnotes.conn.sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_invoice = '%s' and t1.docstatus = 1" % (self.doc.name))
|
|
||||||
if submit_jv:
|
|
||||||
msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.")
|
|
||||||
raise Exception, "Validation Error."
|
|
||||||
|
|
||||||
|
|
||||||
# On Cancel
|
|
||||||
# ----------
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
if cint(self.doc.is_pos) == 1:
|
if cint(self.doc.is_pos) == 1:
|
||||||
if cint(self.doc.update_stock) == 1:
|
if cint(self.doc.update_stock) == 1:
|
||||||
get_obj('Stock Ledger').update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
|
sl = get_obj('Stock Ledger')
|
||||||
|
sl.update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
|
||||||
|
sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
|
||||||
|
|
||||||
self.update_stock_ledger(update_stock = -1)
|
self.update_stock_ledger(update_stock = -1)
|
||||||
else:
|
else:
|
||||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||||
@ -637,51 +636,6 @@ class DocType(TransactionBase):
|
|||||||
|
|
||||||
self.make_gl_entries(is_cancel=1)
|
self.make_gl_entries(is_cancel=1)
|
||||||
|
|
||||||
# Get Warehouse
|
|
||||||
def get_warehouse(self):
|
|
||||||
w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company))
|
|
||||||
w = w and w[0][0] or ''
|
|
||||||
if not w:
|
|
||||||
ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
|
|
||||||
if not ps:
|
|
||||||
msgprint("To make POS entry, please create POS Setting from Setup --> Accounts --> POS Setting and refresh the system.")
|
|
||||||
raise Exception
|
|
||||||
elif not ps[0][1]:
|
|
||||||
msgprint("Please enter warehouse in POS Setting")
|
|
||||||
else:
|
|
||||||
w = ps[0][1]
|
|
||||||
return w
|
|
||||||
|
|
||||||
# on update
|
|
||||||
def on_update(self):
|
|
||||||
# Set default warehouse from pos setting
|
|
||||||
#----------------------------------------
|
|
||||||
if cint(self.doc.is_pos) == 1:
|
|
||||||
self.set_actual_qty()
|
|
||||||
w = self.get_warehouse()
|
|
||||||
if w:
|
|
||||||
for d in getlist(self.doclist, 'entries'):
|
|
||||||
if not d.warehouse:
|
|
||||||
d.warehouse = cstr(w)
|
|
||||||
|
|
||||||
if flt(self.doc.paid_amount) == 0:
|
|
||||||
if self.doc.cash_bank_account:
|
|
||||||
webnotes.conn.set(self.doc, 'paid_amount',
|
|
||||||
(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
|
|
||||||
else:
|
|
||||||
# show message that the amount is not paid
|
|
||||||
webnotes.conn.set(self.doc,'paid_amount',0)
|
|
||||||
webnotes.msgprint("Note: Payment Entry not created since 'Cash/Bank Account' was not specified.")
|
|
||||||
|
|
||||||
else:
|
|
||||||
webnotes.conn.set(self.doc,'paid_amount',0)
|
|
||||||
|
|
||||||
webnotes.conn.set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------------
|
|
||||||
def on_update_after_submit(self):
|
|
||||||
self.convert_into_recurring()
|
|
||||||
|
|
||||||
|
|
||||||
def convert_into_recurring(self):
|
def convert_into_recurring(self):
|
||||||
if self.doc.convert_into_recurring_invoice:
|
if self.doc.convert_into_recurring_invoice:
|
||||||
@ -717,3 +671,7 @@ class DocType(TransactionBase):
|
|||||||
next_date = next_date.strftime("%Y-%m-%d")
|
next_date = next_date.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
webnotes.conn.set(self.doc, 'next_date', next_date)
|
webnotes.conn.set(self.doc, 'next_date', next_date)
|
||||||
|
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
self.convert_into_recurring()
|
||||||
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
# These values are common in all dictionaries
|
# These values are common in all dictionaries
|
||||||
{
|
{
|
||||||
'creation': '2012-06-11 12:09:54',
|
'creation': '2012-07-05 11:04:09',
|
||||||
'docstatus': 0,
|
'docstatus': 0,
|
||||||
'modified': '2012-06-17 21:37:40',
|
'modified': '2012-07-11 12:19:49',
|
||||||
'modified_by': u'Administrator',
|
'modified_by': u'Administrator',
|
||||||
'owner': u'Administrator'
|
'owner': u'Administrator'
|
||||||
},
|
},
|
||||||
@ -350,6 +350,16 @@
|
|||||||
'permlevel': 0
|
'permlevel': 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'sales_bom_help',
|
||||||
|
'fieldtype': u'HTML',
|
||||||
|
'label': u'Sales BOM Help',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
@ -1343,6 +1353,27 @@
|
|||||||
'print_hide': 1
|
'print_hide': 1
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'packing_list',
|
||||||
|
'fieldtype': u'Section Break',
|
||||||
|
'label': u'Packing List',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'packing_details',
|
||||||
|
'fieldtype': u'Table',
|
||||||
|
'label': u'Packing Details',
|
||||||
|
'options': u'Delivery Note Packing Item',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
|
|||||||
@ -24,7 +24,6 @@ from webnotes.model.doclist import getlist, copy_doclist
|
|||||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||||
from webnotes import session, form, is_testing, msgprint, errprint
|
from webnotes import session, form, is_testing, msgprint, errprint
|
||||||
|
|
||||||
set = webnotes.conn.set
|
|
||||||
sql = webnotes.conn.sql
|
sql = webnotes.conn.sql
|
||||||
get_value = webnotes.conn.get_value
|
get_value = webnotes.conn.get_value
|
||||||
in_transaction = webnotes.conn.in_transaction
|
in_transaction = webnotes.conn.in_transaction
|
||||||
@ -46,14 +45,14 @@ class DocType:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
cond = self.get_filter_condition()
|
cond = self.get_filter_condition()
|
||||||
|
cond += self.get_joining_releiving_condition()
|
||||||
|
|
||||||
emp_list = sql("""
|
emp_list = sql("""
|
||||||
select t1.name
|
select t1.name
|
||||||
from `tabEmployee` t1, `tabSalary Structure` t2
|
from `tabEmployee` t1, `tabSalary Structure` t2
|
||||||
where t1.docstatus!=2 and t2.docstatus != 2
|
where t1.docstatus!=2 and t2.docstatus != 2
|
||||||
and ifnull(t1.status, 'Left') = 'Active' and ifnull(t2.is_active, 'No') = 'Yes'
|
|
||||||
and t1.name = t2.employee
|
and t1.name = t2.employee
|
||||||
%s """% cond)
|
%s """% cond, debug=1)
|
||||||
|
|
||||||
return emp_list
|
return emp_list
|
||||||
|
|
||||||
@ -69,12 +68,42 @@ class DocType:
|
|||||||
return cond
|
return cond
|
||||||
|
|
||||||
|
|
||||||
|
def get_joining_releiving_condition(self):
|
||||||
|
m = self.get_month_details(self.doc.fiscal_year, self.doc.month)
|
||||||
|
cond = """
|
||||||
|
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(month_end_date)s'
|
||||||
|
and ifnull(t1.relieving_date, '2199-12-31') >= '%(month_start_date)s'
|
||||||
|
""" % m
|
||||||
|
return cond
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def check_mandatory(self):
|
def check_mandatory(self):
|
||||||
for f in ['company', 'month', 'fiscal_year']:
|
for f in ['company', 'month', 'fiscal_year']:
|
||||||
if not self.doc.fields[f]:
|
if not self.doc.fields[f]:
|
||||||
msgprint("Please select %s to proceed" % f, raise_exception=1)
|
msgprint("Please select %s to proceed" % f, raise_exception=1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_month_details(self, year, month):
|
||||||
|
ysd = sql("select year_start_date from `tabFiscal Year` where name ='%s'"%year)[0][0]
|
||||||
|
if ysd:
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
import calendar, datetime
|
||||||
|
diff_mnt = cint(month)-cint(ysd.month)
|
||||||
|
if diff_mnt<0:
|
||||||
|
diff_mnt = 12-int(ysd.month)+cint(month)
|
||||||
|
msd = ysd + relativedelta(months=diff_mnt) # month start date
|
||||||
|
month_days = cint(calendar.monthrange(cint(msd.year) ,cint(month))[1]) # days in month
|
||||||
|
med = datetime.date(msd.year, cint(month), month_days) # month end date
|
||||||
|
return {
|
||||||
|
'year': msd.year,
|
||||||
|
'month_start_date': msd,
|
||||||
|
'month_end_date': med,
|
||||||
|
'month_days': month_days
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_sal_slip(self):
|
def create_sal_slip(self):
|
||||||
"""
|
"""
|
||||||
Creates salary slip for selected employees if already not created
|
Creates salary slip for selected employees if already not created
|
||||||
@ -82,12 +111,7 @@ class DocType:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
emp_list = self.get_emp_list()
|
emp_list = self.get_emp_list()
|
||||||
log = ""
|
ss_list = []
|
||||||
if emp_list:
|
|
||||||
log = "<table><tr><td colspan = 2>Following Salary Slip has been created: </td></tr><tr><td><u>SAL SLIP ID</u></td><td><u>EMPLOYEE NAME</u></td></tr>"
|
|
||||||
else:
|
|
||||||
log = "<table><tr><td colspan = 2>No employee found for the above selected criteria</td></tr>"
|
|
||||||
|
|
||||||
for emp in emp_list:
|
for emp in emp_list:
|
||||||
if not sql("""select name from `tabSalary Slip`
|
if not sql("""select name from `tabSalary Slip`
|
||||||
where docstatus!= 2 and employee = %s and month = %s and fiscal_year = %s and company = %s
|
where docstatus!= 2 and employee = %s and month = %s and fiscal_year = %s and company = %s
|
||||||
@ -111,10 +135,19 @@ class DocType:
|
|||||||
for d in getlist(ss_obj.doclist, 'deduction_details'):
|
for d in getlist(ss_obj.doclist, 'deduction_details'):
|
||||||
d.save()
|
d.save()
|
||||||
|
|
||||||
log += '<tr><td>' + ss.name + '</td><td>' + ss_obj.doc.employee_name + '</td></tr>'
|
ss_list.append(ss.name)
|
||||||
log += '</table>'
|
|
||||||
|
return self.create_log(ss_list)
|
||||||
|
|
||||||
|
|
||||||
|
def create_log(self, ss_list):
|
||||||
|
log = "<b>No employee for the above selected criteria OR salary slip already created</b>"
|
||||||
|
if ss_list:
|
||||||
|
log = "<b>Created Salary Slip has been created: </b>\
|
||||||
|
<br><br>%s" % '<br>'.join(ss_list)
|
||||||
return log
|
return log
|
||||||
|
|
||||||
|
|
||||||
def get_sal_slip_list(self):
|
def get_sal_slip_list(self):
|
||||||
"""
|
"""
|
||||||
Returns list of salary slips based on selected criteria
|
Returns list of salary slips based on selected criteria
|
||||||
@ -133,27 +166,48 @@ class DocType:
|
|||||||
Submit all salary slips based on selected criteria
|
Submit all salary slips based on selected criteria
|
||||||
"""
|
"""
|
||||||
ss_list = self.get_sal_slip_list()
|
ss_list = self.get_sal_slip_list()
|
||||||
log = ""
|
not_submitted_ss = []
|
||||||
if ss_list:
|
|
||||||
log = """<table>
|
|
||||||
<tr>
|
|
||||||
<td colspan = 2>Following Salary Slip has been submitted: </td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><u>SAL SLIP ID</u></td>
|
|
||||||
<td><u>EMPLOYEE NAME</u></td>
|
|
||||||
</tr>
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
log = "<table><tr><td colspan = 2>No salary slip found to submit for the above selected criteria</td></tr>"
|
|
||||||
|
|
||||||
for ss in ss_list:
|
for ss in ss_list:
|
||||||
ss_obj = get_obj("Salary Slip",ss[0],with_children=1)
|
ss_obj = get_obj("Salary Slip",ss[0],with_children=1)
|
||||||
set(ss_obj.doc, 'docstatus', 1)
|
try:
|
||||||
ss_obj.on_submit()
|
webnotes.conn.set(ss_obj.doc, 'email_check', cint(self.doc.send_mail))
|
||||||
|
if cint(self.doc.send_email) == 1:
|
||||||
|
ss_obj.send_mail_funct()
|
||||||
|
|
||||||
log += '<tr><td>' + ss[0] + '</td><td>' + ss_obj.doc.employee_name + '</td></tr>'
|
webnotes.conn.set(ss_obj.doc, 'docstatus', 1)
|
||||||
log += '</table>'
|
except Exception,e:
|
||||||
|
not_submitted_ss.append(ss[0])
|
||||||
|
msgprint(e)
|
||||||
|
continue
|
||||||
|
|
||||||
|
return self.create_submit_log(ss_list, not_submitted_ss)
|
||||||
|
|
||||||
|
|
||||||
|
def create_submit_log(self, all_ss, not_submitted_ss):
|
||||||
|
log = ''
|
||||||
|
if not all_ss:
|
||||||
|
log = "No salary slip found to submit for the above selected criteria"
|
||||||
|
else:
|
||||||
|
all_ss = [d[0] for d in all_ss]
|
||||||
|
|
||||||
|
submitted_ss = list(set(all_ss) - set(not_submitted_ss))
|
||||||
|
if submitted_ss:
|
||||||
|
mail_sent_msg = self.doc.send_email and " (Mail has been sent to the employee)" or ""
|
||||||
|
log = """
|
||||||
|
<b>Submitted Salary Slips%s:</b>\
|
||||||
|
<br><br> %s <br><br>
|
||||||
|
""" % (mail_sent_msg, '<br>'.join(submitted_ss))
|
||||||
|
|
||||||
|
if not_submitted_ss:
|
||||||
|
log += """
|
||||||
|
<b>Not Submitted Salary Slips: </b>\
|
||||||
|
<br><br> %s <br><br> \
|
||||||
|
Reason: <br>\
|
||||||
|
May be company email id specified in employee master is not valid. <br> \
|
||||||
|
Please mention correct email id in employee master or if you don't want to \
|
||||||
|
send mail, uncheck 'Send Email' checkbox. <br>\
|
||||||
|
Then try to submit Salary Slip again.
|
||||||
|
"""% ('<br>'.join(not_submitted_ss))
|
||||||
return log
|
return log
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -45,9 +45,13 @@ cur_frm.cscript.month = cur_frm.cscript.employee = cur_frm.cscript.fiscal_year;
|
|||||||
// Calculate total if lwp exists
|
// Calculate total if lwp exists
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
cur_frm.cscript.leave_without_pay = function(doc,dt,dn){
|
cur_frm.cscript.leave_without_pay = function(doc,dt,dn){
|
||||||
doc.payment_days = flt(doc.total_days_in_month) - flt(doc.leave_without_pay);
|
if (doc.employee && doc.fiscal_year && doc.month) {
|
||||||
refresh_field('payment_days');
|
$c_obj(make_doclist(doc.doctype,doc.name), 'get_leave_details',doc.leave_without_pay,function(r, rt) {
|
||||||
calculate_all(doc, dt, dn);
|
var doc = locals[dt][dn];
|
||||||
|
cur_frm.refresh();
|
||||||
|
calculate_all(doc, dt, dn);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate all
|
// Calculate all
|
||||||
|
|||||||
@ -39,27 +39,22 @@ class DocType(TransactionBase):
|
|||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
|
|
||||||
|
|
||||||
# autoname
|
|
||||||
#=======================================================
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
self.doc.name = make_autoname('Sal Slip/' +self.doc.employee + '/.#####')
|
self.doc.name = make_autoname('Sal Slip/' +self.doc.employee + '/.#####')
|
||||||
|
|
||||||
# Get employee details
|
|
||||||
#=======================================================
|
|
||||||
def get_emp_and_leave_details(self):
|
|
||||||
# Get payment days
|
|
||||||
if self.doc.fiscal_year and self.doc.month:
|
|
||||||
self.get_leave_details()
|
|
||||||
|
|
||||||
# check sal structure
|
def get_emp_and_leave_details(self):
|
||||||
if self.doc.employee:
|
if self.doc.employee:
|
||||||
|
# Get payment days
|
||||||
|
if self.doc.fiscal_year and self.doc.month:
|
||||||
|
self.get_leave_details()
|
||||||
|
|
||||||
|
# check sal structure
|
||||||
struct = self.check_sal_struct()
|
struct = self.check_sal_struct()
|
||||||
if struct:
|
if struct:
|
||||||
self.pull_sal_struct(struct)
|
self.pull_sal_struct(struct)
|
||||||
|
|
||||||
|
|
||||||
# Check sal structure
|
|
||||||
#=======================================================
|
|
||||||
def check_sal_struct(self):
|
def check_sal_struct(self):
|
||||||
struct = sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee)
|
struct = sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee)
|
||||||
if not struct:
|
if not struct:
|
||||||
@ -67,8 +62,7 @@ class DocType(TransactionBase):
|
|||||||
self.doc.employee = ''
|
self.doc.employee = ''
|
||||||
return struct and struct[0][0] or ''
|
return struct and struct[0][0] or ''
|
||||||
|
|
||||||
# Pull struct details
|
|
||||||
#=======================================================
|
|
||||||
def pull_sal_struct(self, struct):
|
def pull_sal_struct(self, struct):
|
||||||
self.doclist = self.doc.clear_table(self.doclist, 'earning_details')
|
self.doclist = self.doc.clear_table(self.doclist, 'earning_details')
|
||||||
self.doclist = self.doc.clear_table(self.doclist, 'deduction_details')
|
self.doclist = self.doc.clear_table(self.doclist, 'deduction_details')
|
||||||
@ -81,41 +75,48 @@ class DocType(TransactionBase):
|
|||||||
self.doc.esic_no = basic_info[0][2]
|
self.doc.esic_no = basic_info[0][2]
|
||||||
self.doc.pf_no = basic_info[0][3]
|
self.doc.pf_no = basic_info[0][3]
|
||||||
|
|
||||||
# Get leave details
|
|
||||||
#=======================================================
|
def get_leave_details(self, lwp=None):
|
||||||
def get_leave_details(self):
|
m = get_obj('Salary Manager').get_month_details(self.doc.fiscal_year, self.doc.month)
|
||||||
m = self.get_month_details()
|
|
||||||
lwp = self.calculate_lwp(m)
|
if not lwp:
|
||||||
self.doc.total_days_in_month = m[3]
|
lwp = self.calculate_lwp(m)
|
||||||
|
self.doc.total_days_in_month = m['month_days']
|
||||||
self.doc.leave_without_pay = lwp
|
self.doc.leave_without_pay = lwp
|
||||||
self.doc.payment_days = flt(m[3]) - flt(lwp)
|
payment_days = flt(self.get_payment_days(m)) - flt(lwp)
|
||||||
|
self.doc.payment_days = payment_days > 0 and payment_days or 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_payment_days(self, m):
|
||||||
|
payment_days = m['month_days']
|
||||||
|
emp = webnotes.conn.sql("select date_of_joining, relieving_date from `tabEmployee` \
|
||||||
|
where name = %s", self.doc.employee, as_dict=1)[0]
|
||||||
|
|
||||||
|
if emp['relieving_date']:
|
||||||
|
if getdate(emp['relieving_date']) > m['month_start_date'] and getdate(emp['relieving_date']) < m['month_end_date']:
|
||||||
|
payment_days = getdate(emp['relieving_date']).day
|
||||||
|
elif getdate(emp['relieving_date']) < m['month_start_date']:
|
||||||
|
payment_days = 0
|
||||||
|
|
||||||
|
if emp['date_of_joining']:
|
||||||
|
if getdate(emp['date_of_joining']) > m['month_start_date'] and getdate(emp['date_of_joining']) < m['month_end_date']:
|
||||||
|
payment_days = payment_days - getdate(emp['date_of_joining']).day + 1
|
||||||
|
elif getdate(emp['date_of_joining']) > m['month_end_date']:
|
||||||
|
payment_days = 0
|
||||||
|
|
||||||
|
return payment_days
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Get month details
|
|
||||||
#=======================================================
|
|
||||||
def get_month_details(self):
|
|
||||||
ysd = sql("select year_start_date from `tabFiscal Year` where name ='%s'"%self.doc.fiscal_year)[0][0]
|
|
||||||
if ysd:
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
import calendar, datetime
|
|
||||||
mnt = int(self.doc.month)
|
|
||||||
diff_mnt = int(mnt)-int(ysd.month)
|
|
||||||
if diff_mnt<0:
|
|
||||||
diff_mnt = 12-int(ysd.month)+int(mnt)
|
|
||||||
msd = ysd + relativedelta(months=diff_mnt) # month start date
|
|
||||||
month_days = cint(calendar.monthrange(cint(msd.year) ,cint(self.doc.month))[1]) # days in month
|
|
||||||
med = datetime.date(msd.year, cint(self.doc.month), month_days) # month end date
|
|
||||||
return msd.year, msd, med, month_days
|
|
||||||
|
|
||||||
# Calculate LWP
|
|
||||||
#=======================================================
|
|
||||||
def calculate_lwp(self, m):
|
def calculate_lwp(self, m):
|
||||||
holidays = sql("select t1.holiday_date from `tabHoliday` t1, tabEmployee t2 where t1.parent = t2.holiday_list and t2.name = '%s' and t1.holiday_date between '%s' and '%s'" % (self.doc.employee, m[1], m[2]))
|
holidays = sql("select t1.holiday_date from `tabHoliday` t1, tabEmployee t2 where t1.parent = t2.holiday_list and t2.name = '%s' and t1.holiday_date between '%s' and '%s'" % (self.doc.employee, m['month_start_date'], m['month_end_date']))
|
||||||
if not holidays:
|
if not holidays:
|
||||||
holidays = sql("select t1.holiday_date from `tabHoliday` t1, `tabHoliday List` t2 where t1.parent = t2.name and ifnull(t2.is_default, 0) = 1 and t2.fiscal_year = '%s'" % self.doc.fiscal_year)
|
holidays = sql("select t1.holiday_date from `tabHoliday` t1, `tabHoliday List` t2 where t1.parent = t2.name and ifnull(t2.is_default, 0) = 1 and t2.fiscal_year = '%s'" % self.doc.fiscal_year)
|
||||||
holidays = [cstr(i[0]) for i in holidays]
|
holidays = [cstr(i[0]) for i in holidays]
|
||||||
lwp = 0
|
lwp = 0
|
||||||
for d in range(m[3]):
|
for d in range(m['month_days']):
|
||||||
dt = add_days(cstr(m[1]), d)
|
dt = add_days(cstr(m['month_start_date']), d)
|
||||||
if dt not in holidays:
|
if dt not in holidays:
|
||||||
leave = sql("""
|
leave = sql("""
|
||||||
select t1.name, t1.half_day
|
select t1.name, t1.half_day
|
||||||
@ -130,8 +131,7 @@ class DocType(TransactionBase):
|
|||||||
lwp = cint(leave[0][1]) and lwp + 0.5 or lwp + 1
|
lwp = cint(leave[0][1]) and lwp + 0.5 or lwp + 1
|
||||||
return lwp
|
return lwp
|
||||||
|
|
||||||
# Check existing
|
|
||||||
#=======================================================
|
|
||||||
def check_existing(self):
|
def check_existing(self):
|
||||||
ret_exist = sql("select name from `tabSalary Slip` where month = '%s' and fiscal_year = '%s' and docstatus != 2 and employee = '%s' and name !='%s'" % (self.doc.month,self.doc.fiscal_year,self.doc.employee,self.doc.name))
|
ret_exist = sql("select name from `tabSalary Slip` where month = '%s' and fiscal_year = '%s' and docstatus != 2 and employee = '%s' and name !='%s'" % (self.doc.month,self.doc.fiscal_year,self.doc.employee,self.doc.name))
|
||||||
if ret_exist:
|
if ret_exist:
|
||||||
@ -139,8 +139,7 @@ class DocType(TransactionBase):
|
|||||||
self.doc.employee = ''
|
self.doc.employee = ''
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
# Validate
|
|
||||||
#=======================================================
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.check_existing()
|
self.check_existing()
|
||||||
dcc = TransactionBase().get_company_currency(self.doc.company)
|
dcc = TransactionBase().get_company_currency(self.doc.company)
|
||||||
@ -155,6 +154,8 @@ class DocType(TransactionBase):
|
|||||||
for d in getlist(self.doclist, 'earning_details'):
|
for d in getlist(self.doclist, 'earning_details'):
|
||||||
if cint(d.e_depends_on_lwp) == 1:
|
if cint(d.e_depends_on_lwp) == 1:
|
||||||
d.e_modified_amount = round(flt(d.e_amount)*flt(self.doc.payment_days)/cint(self.doc.total_days_in_month), 2)
|
d.e_modified_amount = round(flt(d.e_amount)*flt(self.doc.payment_days)/cint(self.doc.total_days_in_month), 2)
|
||||||
|
elif not self.doc.payment_days:
|
||||||
|
d.e_modified_amount = 0
|
||||||
self.doc.gross_pay += d.e_modified_amount
|
self.doc.gross_pay += d.e_modified_amount
|
||||||
|
|
||||||
def calculate_ded_total(self):
|
def calculate_ded_total(self):
|
||||||
@ -165,6 +166,9 @@ class DocType(TransactionBase):
|
|||||||
for d in getlist(self.doclist, 'deduction_details'):
|
for d in getlist(self.doclist, 'deduction_details'):
|
||||||
if cint(d.d_depends_on_lwp) == 1:
|
if cint(d.d_depends_on_lwp) == 1:
|
||||||
d.d_modified_amount = round(flt(d.d_amount)*flt(self.doc.payment_days)/cint(self.doc.total_days_in_month), 2)
|
d.d_modified_amount = round(flt(d.d_amount)*flt(self.doc.payment_days)/cint(self.doc.total_days_in_month), 2)
|
||||||
|
elif not self.doc.payment_days:
|
||||||
|
d.d_modified_amount = 0
|
||||||
|
|
||||||
self.doc.total_deduction += d.d_modified_amount
|
self.doc.total_deduction += d.d_modified_amount
|
||||||
|
|
||||||
def calculate_net_pay(self):
|
def calculate_net_pay(self):
|
||||||
@ -176,17 +180,12 @@ class DocType(TransactionBase):
|
|||||||
self.doc.net_pay = flt(self.doc.gross_pay) - flt(self.doc.total_deduction)
|
self.doc.net_pay = flt(self.doc.gross_pay) - flt(self.doc.total_deduction)
|
||||||
self.doc.rounded_total = round(self.doc.net_pay)
|
self.doc.rounded_total = round(self.doc.net_pay)
|
||||||
|
|
||||||
# ON SUBMIT
|
|
||||||
#=======================================================
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
if(self.doc.email_check == 1):
|
if(self.doc.email_check == 1):
|
||||||
self.send_mail_funct()
|
self.send_mail_funct()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Send mail
|
|
||||||
#=======================================================
|
|
||||||
def send_mail_funct(self):
|
def send_mail_funct(self):
|
||||||
from webnotes.utils.email_lib import sendmail
|
from webnotes.utils.email_lib import sendmail
|
||||||
emailid_ret=sql("select company_email from `tabEmployee` where name = '%s'"%self.doc.employee)
|
emailid_ret=sql("select company_email from `tabEmployee` where name = '%s'"%self.doc.employee)
|
||||||
@ -281,4 +280,4 @@ class DocType(TransactionBase):
|
|||||||
</table></div>'''%(cstr(letter_head[0][0]),cstr(self.doc.employee), cstr(self.doc.employee_name), cstr(self.doc.month), cstr(self.doc.fiscal_year), cstr(self.doc.department), cstr(self.doc.branch), cstr(self.doc.designation), cstr(self.doc.grade), cstr(self.doc.bank_account_no), cstr(self.doc.bank_name), cstr(self.doc.arrear_amount), cstr(self.doc.payment_days), earn_table, ded_table, cstr(flt(self.doc.gross_pay)), cstr(flt(self.doc.total_deduction)), cstr(flt(self.doc.net_pay)), cstr(self.doc.total_in_words))
|
</table></div>'''%(cstr(letter_head[0][0]),cstr(self.doc.employee), cstr(self.doc.employee_name), cstr(self.doc.month), cstr(self.doc.fiscal_year), cstr(self.doc.department), cstr(self.doc.branch), cstr(self.doc.designation), cstr(self.doc.grade), cstr(self.doc.bank_account_no), cstr(self.doc.bank_name), cstr(self.doc.arrear_amount), cstr(self.doc.payment_days), earn_table, ded_table, cstr(flt(self.doc.gross_pay)), cstr(flt(self.doc.total_deduction)), cstr(flt(self.doc.net_pay)), cstr(self.doc.total_in_words))
|
||||||
sendmail([receiver], subject=subj, msg = msg)
|
sendmail([receiver], subject=subj, msg = msg)
|
||||||
else:
|
else:
|
||||||
msgprint("Company Email ID not found.")
|
msgprint("Company Email ID not found, hence mail not sent")
|
||||||
|
|||||||
47
erpnext/hr/doctype/salary_structure/listview.js
Normal file
47
erpnext/hr/doctype/salary_structure/listview.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// render
|
||||||
|
wn.doclistviews['Salary Structure'] = wn.views.ListView.extend({
|
||||||
|
init: function(d) {
|
||||||
|
this._super(d)
|
||||||
|
this.fields = this.fields.concat([
|
||||||
|
"`tabSalary Structure`.employee_name",
|
||||||
|
"`tabSalary Structure`.designation",
|
||||||
|
"`tabSalary Structure`.branch",
|
||||||
|
"`tabSalary Structure`.net_pay",
|
||||||
|
"`tabSalary Structure`.from_date",
|
||||||
|
"`tabSalary Structure`.to_date",
|
||||||
|
"`tabSalary Structure`.company"
|
||||||
|
]);
|
||||||
|
this.stats = this.stats.concat(['company']);
|
||||||
|
},
|
||||||
|
|
||||||
|
prepare_data: function(data) {
|
||||||
|
this._super(data);
|
||||||
|
var concat_list = [];
|
||||||
|
data.designation && concat_list.push(data.designation);
|
||||||
|
data.branch && concat_list.push(data.branch);
|
||||||
|
data.description = concat_list.join(", ");
|
||||||
|
data.period = data.from_date + (data.to_date && ' to ' + data.to_date);
|
||||||
|
},
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
{width: '2%', content: 'check'},
|
||||||
|
{width: '2%', content: 'docstatus'},
|
||||||
|
{width: '13%', content: 'name'},
|
||||||
|
{width: '18%', content: 'employee_name'},
|
||||||
|
{width: '24%', content: 'description+tags', css: {'color': '#aaa'}},
|
||||||
|
{width: '26%', content:'period', css: {'text-align': 'right', 'color':'#aaa'}},
|
||||||
|
{
|
||||||
|
width: '15%',
|
||||||
|
content: function(parent, data) {
|
||||||
|
$(parent).html(
|
||||||
|
(
|
||||||
|
data.company
|
||||||
|
? wn.boot.company[data.company].default_currency
|
||||||
|
: sys_defaults.currency
|
||||||
|
)
|
||||||
|
+ ' ' + fmt_money(data.net_pay));
|
||||||
|
},
|
||||||
|
css: {'text-align': 'right'},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
@ -106,7 +106,6 @@ class DocType:
|
|||||||
return ret_item
|
return ret_item
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_rm_rate(self, arg):
|
def get_rm_rate(self, arg):
|
||||||
""" Get raw material rate as per selected method, if bom exists takes bom cost """
|
""" Get raw material rate as per selected method, if bom exists takes bom cost """
|
||||||
|
|
||||||
@ -293,7 +292,6 @@ class DocType:
|
|||||||
self.validate_main_item()
|
self.validate_main_item()
|
||||||
self.validate_operations()
|
self.validate_operations()
|
||||||
self.validate_materials()
|
self.validate_materials()
|
||||||
self.validate_operations()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -353,8 +351,6 @@ class DocType:
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Get Current Flat BOM Items
|
# Get Current Flat BOM Items
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
def get_current_flat_bom_items(self):
|
def get_current_flat_bom_items(self):
|
||||||
|
|||||||
@ -127,10 +127,34 @@ cur_frm.cscript.dynamic_label = function(doc, cdt, cdn, base_curr, callback) {
|
|||||||
cur_frm.cscript.base_currency = base_curr;
|
cur_frm.cscript.base_currency = base_curr;
|
||||||
set_dynamic_label_par(doc, cdt, cdn, base_curr);
|
set_dynamic_label_par(doc, cdt, cdn, base_curr);
|
||||||
set_dynamic_label_child(doc, cdt, cdn, base_curr);
|
set_dynamic_label_child(doc, cdt, cdn, base_curr);
|
||||||
|
set_sales_bom_help(doc);
|
||||||
|
|
||||||
if (callback) callback(doc, cdt, cdn);
|
if (callback) callback(doc, cdt, cdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Help for Sales BOM items
|
||||||
|
var set_sales_bom_help = function(doc) {
|
||||||
|
if (getchildren('Delivery Note Packing Item', doc.name, 'packing_details').length) {
|
||||||
|
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
|
||||||
|
|
||||||
|
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||||
|
help_msg = "<div class='help-box'> \
|
||||||
|
For 'Sales BOM' items, warehouse, serial no and batch no \
|
||||||
|
will be considered from the 'Packing List' table. \
|
||||||
|
If warehouse and batch no are same for all packing items for any 'Sales BOM' item, \
|
||||||
|
those values can be entered in the main item table, values will be copied to 'Packing List' table. \
|
||||||
|
</div>";
|
||||||
|
get_field(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
|
||||||
|
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||||
|
get_field(doc.doctype, 'sales_bom_help', doc.name).options = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refresh_field('sales_bom_help');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// hide / unhide price list currency based on availability of price list in customer's currency
|
// hide / unhide price list currency based on availability of price list in customer's currency
|
||||||
//---------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -385,7 +385,7 @@ class DocType(TransactionBase):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def get_item_list(self, obj, is_stopped):
|
def get_item_list(self, obj, is_stopped=0):
|
||||||
"""get item list"""
|
"""get item list"""
|
||||||
il = []
|
il = []
|
||||||
for d in getlist(obj.doclist,obj.fname):
|
for d in getlist(obj.doclist,obj.fname):
|
||||||
@ -413,7 +413,7 @@ class DocType(TransactionBase):
|
|||||||
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({
|
il.append({
|
||||||
'warehouse': d.warehouse,
|
'warehouse': p.warehouse,
|
||||||
'reserved_warehouse': reserved_wh,
|
'reserved_warehouse': reserved_wh,
|
||||||
'item_code': p.item_code,
|
'item_code': p.item_code,
|
||||||
'qty': flt(p.qty),
|
'qty': flt(p.qty),
|
||||||
@ -496,23 +496,21 @@ class DocType(TransactionBase):
|
|||||||
pi.qty = flt(qty)
|
pi.qty = flt(qty)
|
||||||
pi.actual_qty = bin and flt(bin['actual_qty']) or 0
|
pi.actual_qty = bin and flt(bin['actual_qty']) or 0
|
||||||
pi.projected_qty = bin and flt(bin['projected_qty']) or 0
|
pi.projected_qty = bin and flt(bin['projected_qty']) or 0
|
||||||
pi.warehouse = warehouse
|
|
||||||
pi.prevdoc_doctype = line.prevdoc_doctype
|
pi.prevdoc_doctype = line.prevdoc_doctype
|
||||||
if packing_item_code == line.item_code:
|
if not pi.warehouse:
|
||||||
pi.serial_no = cstr(line.serial_no)
|
pi.warehouse = warehouse
|
||||||
|
if not pi.batch_no:
|
||||||
pi.batch_no = cstr(line.batch_no)
|
pi.batch_no = cstr(line.batch_no)
|
||||||
pi.idx = self.packing_list_idx
|
pi.idx = self.packing_list_idx
|
||||||
|
|
||||||
# has to be saved, since this function is called on_update of delivery note
|
# saved, since this function is called on_update of delivery note
|
||||||
pi.save()
|
pi.save()
|
||||||
|
|
||||||
self.packing_list_idx += 1
|
self.packing_list_idx += 1
|
||||||
|
|
||||||
|
|
||||||
# ------------------
|
|
||||||
# make packing list from sales bom if exists or directly copy item with balance
|
|
||||||
# ------------------
|
|
||||||
def make_packing_list(self, obj, fname):
|
def make_packing_list(self, obj, fname):
|
||||||
|
"""make packing list for sales bom item"""
|
||||||
self.packing_list_idx = 0
|
self.packing_list_idx = 0
|
||||||
parent_items = []
|
parent_items = []
|
||||||
for d in getlist(obj.doclist, fname):
|
for d in getlist(obj.doclist, fname):
|
||||||
@ -520,10 +518,9 @@ class DocType(TransactionBase):
|
|||||||
if self.has_sales_bom(d.item_code):
|
if self.has_sales_bom(d.item_code):
|
||||||
for i in self.get_sales_bom_items(d.item_code):
|
for i in self.get_sales_bom_items(d.item_code):
|
||||||
self.update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), warehouse, d)
|
self.update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), warehouse, d)
|
||||||
else:
|
|
||||||
self.update_packing_list_item(obj, d.item_code, d.qty, warehouse, d)
|
if [d.item_code, d.name] not in parent_items:
|
||||||
if [d.item_code, d.name] not in parent_items:
|
parent_items.append([d.item_code, d.name])
|
||||||
parent_items.append([d.item_code, d.name])
|
|
||||||
|
|
||||||
self.cleanup_packing_list(obj, parent_items)
|
self.cleanup_packing_list(obj, parent_items)
|
||||||
|
|
||||||
|
|||||||
@ -49,8 +49,7 @@ class DocType:
|
|||||||
master_dict = {'Fiscal Year':{
|
master_dict = {'Fiscal Year':{
|
||||||
'year': curr_fiscal_year,
|
'year': curr_fiscal_year,
|
||||||
'year_start_date': fy_start_date,
|
'year_start_date': fy_start_date,
|
||||||
'company': args.get('company_name'),
|
'company': args.get('company_name')}}
|
||||||
'is_fiscal_year_closed': 'No'}}
|
|
||||||
self.create_records(master_dict)
|
self.create_records(master_dict)
|
||||||
|
|
||||||
# Company
|
# Company
|
||||||
|
|||||||
@ -138,7 +138,7 @@ $.extend(erpnext.complete_setup, {
|
|||||||
'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', 'El Salvador',
|
'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', 'El Salvador',
|
||||||
'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Federated States of Micronesia',
|
'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Federated States of Micronesia',
|
||||||
'Fiji', 'Finland', 'France', 'Gabon', 'Georgia', 'Germany', 'Ghana', 'Greece',
|
'Fiji', 'Finland', 'France', 'Gabon', 'Georgia', 'Germany', 'Ghana', 'Greece',
|
||||||
'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras',
|
'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras', 'Hong Kong'
|
||||||
'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Israel', 'Italy',
|
'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Israel', 'Italy',
|
||||||
'Jamaica', 'Japan', 'Jordan', 'Kazakhstan', 'Kenya', 'Kingdom of the Netherlands',
|
'Jamaica', 'Japan', 'Jordan', 'Kazakhstan', 'Kenya', 'Kingdom of the Netherlands',
|
||||||
'Kiribati', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia',
|
'Kiribati', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia',
|
||||||
@ -147,7 +147,7 @@ $.extend(erpnext.complete_setup, {
|
|||||||
'Mexico', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Morocco', 'Mozambique',
|
'Mexico', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Morocco', 'Mozambique',
|
||||||
'Myanmar', 'Namibia', 'Nauru', 'Nepal', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria',
|
'Myanmar', 'Namibia', 'Nauru', 'Nepal', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria',
|
||||||
'North Korea', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Panama', 'Papua New Guinea',
|
'North Korea', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Panama', 'Papua New Guinea',
|
||||||
'Paraguay', "People's Republic of China", 'Peru', 'Philippines', 'Poland', 'Portugal',
|
'Paraguay', "China", 'Peru', 'Philippines', 'Poland', 'Portugal',
|
||||||
'Qatar', 'Republic of Ireland', 'Republic of the Congo', 'Romania', 'Russia', 'Rwanda',
|
'Qatar', 'Republic of Ireland', 'Republic of the Congo', 'Romania', 'Russia', 'Rwanda',
|
||||||
'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Vincent and the Grenadines', 'Samoa',
|
'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Vincent and the Grenadines', 'Samoa',
|
||||||
'San Marino', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone',
|
'San Marino', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone',
|
||||||
@ -252,6 +252,11 @@ $.extend(erpnext.complete_setup, {
|
|||||||
'Cape Verde': ['Atlantic/Cape_Verde'],
|
'Cape Verde': ['Atlantic/Cape_Verde'],
|
||||||
'Central African Republic': ['Africa/Bangui'],
|
'Central African Republic': ['Africa/Bangui'],
|
||||||
'Chad': ['Africa/Ndjamena'],
|
'Chad': ['Africa/Ndjamena'],
|
||||||
|
'China': ['Asia/Shanghai',
|
||||||
|
'Asia/Harbin',
|
||||||
|
'Asia/Chongqing',
|
||||||
|
'Asia/Urumqi',
|
||||||
|
'Asia/Kashgar'],
|
||||||
'Chile': ['America/Santiago', 'Pacific/Easter'],
|
'Chile': ['America/Santiago', 'Pacific/Easter'],
|
||||||
'Colombia': ['America/Bogota'],
|
'Colombia': ['America/Bogota'],
|
||||||
'Comoros': ['Indian/Comoro'],
|
'Comoros': ['Indian/Comoro'],
|
||||||
@ -292,6 +297,7 @@ $.extend(erpnext.complete_setup, {
|
|||||||
'Guyana': ['America/Guyana'],
|
'Guyana': ['America/Guyana'],
|
||||||
'Haiti': ['America/Guatemala'],
|
'Haiti': ['America/Guatemala'],
|
||||||
'Honduras': ['America/Tegucigalpa'],
|
'Honduras': ['America/Tegucigalpa'],
|
||||||
|
'Hong Kong': ['Asia/Hong_Kong'],
|
||||||
'Hungary': ['Europe/Budapest'],
|
'Hungary': ['Europe/Budapest'],
|
||||||
'Iceland': ['Atlantic/Reykjavik'],
|
'Iceland': ['Atlantic/Reykjavik'],
|
||||||
'India': ['Asia/Calcutta'],
|
'India': ['Asia/Calcutta'],
|
||||||
@ -365,11 +371,6 @@ $.extend(erpnext.complete_setup, {
|
|||||||
'Panama': ['America/Panama'],
|
'Panama': ['America/Panama'],
|
||||||
'Papua New Guinea': ['Pacific/Port_Moresby'],
|
'Papua New Guinea': ['Pacific/Port_Moresby'],
|
||||||
'Paraguay': ['America/Asuncion'],
|
'Paraguay': ['America/Asuncion'],
|
||||||
"People's Republic of China": ['Asia/Shanghai',
|
|
||||||
'Asia/Harbin',
|
|
||||||
'Asia/Chongqing',
|
|
||||||
'Asia/Urumqi',
|
|
||||||
'Asia/Kashgar'],
|
|
||||||
'Peru': ['America/Lima'],
|
'Peru': ['America/Lima'],
|
||||||
'Philippines': ['Asia/Manila'],
|
'Philippines': ['Asia/Manila'],
|
||||||
'Poland': ['Europe/Warsaw'],
|
'Poland': ['Europe/Warsaw'],
|
||||||
|
|||||||
@ -197,51 +197,6 @@ class DocType(TransactionBase):
|
|||||||
get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name)
|
get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||||
|
|
||||||
|
|
||||||
def validate_prevdoc_details(self):
|
|
||||||
for d in getlist(self.doclist,'delivery_note_details'):
|
|
||||||
prevdoc = d.prevdoc_doctype
|
|
||||||
prevdoc_docname = d.prevdoc_docname
|
|
||||||
|
|
||||||
if prevdoc_docname and prevdoc:
|
|
||||||
# Validates Transaction Date of DN and previous doc (i.e. SO , PO, PR)
|
|
||||||
trans_date = sql("select posting_date from `tab%s` where name = '%s'" %(prevdoc,prevdoc_docname))[0][0]
|
|
||||||
if trans_date and getdate(self.doc.posting_date) < (trans_date):
|
|
||||||
msgprint("Your Posting Date cannot be before "+cstr(prevdoc)+" Date.")
|
|
||||||
raise Exception
|
|
||||||
# Validates DN and previous doc details
|
|
||||||
get_name = sql("select name from `tab%s` where name = '%s'" % (prevdoc, prevdoc_docname))
|
|
||||||
name = get_name and get_name[0][0] or ''
|
|
||||||
if name: #check for incorrect docname
|
|
||||||
if prevdoc == 'Sales Order':
|
|
||||||
dt = sql("select company, docstatus, customer, currency, sales_partner from `tab%s` where name = '%s'" % (prevdoc, name))
|
|
||||||
cust_name = dt and dt[0][2] or ''
|
|
||||||
if cust_name != self.doc.customer:
|
|
||||||
msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " customer :" + cstr(cust_name) + " does not match with customer : " + cstr(self.doc.customer) + " of current document.")
|
|
||||||
raise Exception, "Validation Error. "
|
|
||||||
sal_partner = dt and dt[0][4] or ''
|
|
||||||
if sal_partner != self.doc.sales_partner:
|
|
||||||
msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " sales partner name :" + cstr(sal_partner) + " does not match with sales partner name : " + cstr(self.doc.sales_partner_name) + " of current document.")
|
|
||||||
raise Exception, "Validation Error. "
|
|
||||||
else:
|
|
||||||
dt = sql("select company, docstatus, supplier, currency from `tab%s` where name = '%s'" % (prevdoc, name))
|
|
||||||
supp_name = dt and dt[0][2] or ''
|
|
||||||
company_name = dt and dt[0][0] or ''
|
|
||||||
docstatus = dt and dt[0][1] or 0
|
|
||||||
currency = dt and dt[0][3] or ''
|
|
||||||
if (currency != self.doc.currency):
|
|
||||||
msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " currency : "+ cstr(currency) + "does not match with Currency: " + cstr(self.doc.currency) + "of current document")
|
|
||||||
raise Exception, "Validation Error."
|
|
||||||
if (company_name != self.doc.company):
|
|
||||||
msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " does not belong to the Company: " + cstr(self.doc.company_name))
|
|
||||||
raise Exception, "Validation Error."
|
|
||||||
if (docstatus != 1):
|
|
||||||
msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not Submitted Document.")
|
|
||||||
raise Exception, "Validation Error."
|
|
||||||
else:
|
|
||||||
msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not a valid " + cstr(prevdoc))
|
|
||||||
raise Exception, "Validation Error."
|
|
||||||
|
|
||||||
|
|
||||||
def validate_for_items(self):
|
def validate_for_items(self):
|
||||||
check_list, chk_dupl_itm = [], []
|
check_list, chk_dupl_itm = [], []
|
||||||
for d in getlist(self.doclist,'delivery_note_details'):
|
for d in getlist(self.doclist,'delivery_note_details'):
|
||||||
@ -292,11 +247,22 @@ class DocType(TransactionBase):
|
|||||||
set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_no, self.doc.name))
|
set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_no, self.doc.name))
|
||||||
# Check for Approving Authority
|
# Check for Approving Authority
|
||||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
|
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
|
||||||
|
|
||||||
|
# validate serial no for item table (non-sales-bom item) and packing list (sales-bom item)
|
||||||
sl_obj = get_obj("Stock Ledger")
|
sl_obj = get_obj("Stock Ledger")
|
||||||
|
sl_obj.validate_serial_no(self, 'delivery_note_details')
|
||||||
|
sl_obj.validate_serial_no_warehouse(self, 'delivery_note_details')
|
||||||
sl_obj.validate_serial_no(self, 'packing_details')
|
sl_obj.validate_serial_no(self, 'packing_details')
|
||||||
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
|
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
|
||||||
|
|
||||||
|
# update delivery details in serial no
|
||||||
|
sl_obj.update_serial_record(self, 'delivery_note_details', is_submit = 1, is_incoming = 0)
|
||||||
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
|
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
|
||||||
|
|
||||||
|
# update delivered qty in sales order
|
||||||
get_obj("Sales Common").update_prevdoc_detail(1,self)
|
get_obj("Sales Common").update_prevdoc_detail(1,self)
|
||||||
|
|
||||||
|
# create stock ledger entry
|
||||||
self.update_stock_ledger(update_stock = 1)
|
self.update_stock_ledger(update_stock = 1)
|
||||||
|
|
||||||
self.credit_limit()
|
self.credit_limit()
|
||||||
@ -332,10 +298,14 @@ class DocType(TransactionBase):
|
|||||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||||
sales_com_obj.check_stop_sales_order(self)
|
sales_com_obj.check_stop_sales_order(self)
|
||||||
self.check_next_docstatus()
|
self.check_next_docstatus()
|
||||||
get_obj('Stock Ledger').update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
|
|
||||||
|
# remove delivery details from serial no
|
||||||
|
sl = get_obj('Stock Ledger')
|
||||||
|
sl.update_serial_record(self, 'delivery_note_details', is_submit = 0, is_incoming = 0)
|
||||||
|
sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
|
||||||
|
|
||||||
sales_com_obj.update_prevdoc_detail(0,self)
|
sales_com_obj.update_prevdoc_detail(0,self)
|
||||||
self.update_stock_ledger(update_stock = -1)
|
self.update_stock_ledger(update_stock = -1)
|
||||||
# :::::: set DN status :::::::
|
|
||||||
set(self.doc, 'status', 'Cancelled')
|
set(self.doc, 'status', 'Cancelled')
|
||||||
self.cancel_packing_slips()
|
self.cancel_packing_slips()
|
||||||
|
|
||||||
@ -435,7 +405,8 @@ class DocType(TransactionBase):
|
|||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
|
get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
|
||||||
self.set_actual_qty()
|
sl = get_obj('Stock Ledger')
|
||||||
get_obj('Stock Ledger').scrub_serial_nos(self)
|
sl.scrub_serial_nos(self)
|
||||||
|
sl.scrub_serial_nos(self, 'packing_details')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
# These values are common in all dictionaries
|
# These values are common in all dictionaries
|
||||||
{
|
{
|
||||||
'creation': '2012-05-15 12:15:05',
|
'creation': '2012-06-11 12:10:09',
|
||||||
'docstatus': 0,
|
'docstatus': 0,
|
||||||
'modified': '2012-05-18 18:06:26',
|
'modified': '2012-07-11 11:56:53',
|
||||||
'modified_by': u'Administrator',
|
'modified_by': u'Administrator',
|
||||||
'owner': u'Administrator'
|
'owner': u'Administrator'
|
||||||
},
|
},
|
||||||
@ -72,26 +72,14 @@
|
|||||||
|
|
||||||
# DocPerm
|
# DocPerm
|
||||||
{
|
{
|
||||||
'amend': 1,
|
'amend': 0,
|
||||||
'cancel': 1,
|
'cancel': 0,
|
||||||
'create': 1,
|
'create': 0,
|
||||||
'doctype': u'DocPerm',
|
'doctype': u'DocPerm',
|
||||||
'permlevel': 0,
|
'permlevel': 1,
|
||||||
'role': u'Sales User',
|
'role': u'Material User',
|
||||||
'submit': 1,
|
'submit': 0,
|
||||||
'write': 1
|
'write': 0
|
||||||
},
|
|
||||||
|
|
||||||
# DocPerm
|
|
||||||
{
|
|
||||||
'amend': 1,
|
|
||||||
'cancel': 1,
|
|
||||||
'create': 1,
|
|
||||||
'doctype': u'DocPerm',
|
|
||||||
'permlevel': 0,
|
|
||||||
'role': u'Material Master Manager',
|
|
||||||
'submit': 1,
|
|
||||||
'write': 1
|
|
||||||
},
|
},
|
||||||
|
|
||||||
# DocPerm
|
# DocPerm
|
||||||
@ -108,16 +96,72 @@
|
|||||||
|
|
||||||
# DocPerm
|
# DocPerm
|
||||||
{
|
{
|
||||||
|
'amend': 0,
|
||||||
|
'cancel': 0,
|
||||||
|
'create': 0,
|
||||||
'doctype': u'DocPerm',
|
'doctype': u'DocPerm',
|
||||||
'permlevel': 1,
|
'permlevel': 1,
|
||||||
'role': u'All'
|
'role': u'Material Manager',
|
||||||
|
'submit': 0,
|
||||||
|
'write': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocPerm
|
||||||
|
{
|
||||||
|
'amend': 1,
|
||||||
|
'cancel': 1,
|
||||||
|
'create': 1,
|
||||||
|
'doctype': u'DocPerm',
|
||||||
|
'permlevel': 0,
|
||||||
|
'role': u'Sales User',
|
||||||
|
'submit': 1,
|
||||||
|
'write': 1
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocPerm
|
||||||
|
{
|
||||||
|
'amend': 0,
|
||||||
|
'cancel': 0,
|
||||||
|
'create': 0,
|
||||||
|
'doctype': u'DocPerm',
|
||||||
|
'permlevel': 1,
|
||||||
|
'role': u'Sales User',
|
||||||
|
'submit': 0,
|
||||||
|
'write': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocPerm
|
||||||
|
{
|
||||||
|
'cancel': 0,
|
||||||
|
'create': 0,
|
||||||
|
'doctype': u'DocPerm',
|
||||||
|
'permlevel': 0,
|
||||||
|
'role': u'Accounts User',
|
||||||
|
'submit': 0,
|
||||||
|
'write': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocPerm
|
||||||
|
{
|
||||||
|
'doctype': u'DocPerm',
|
||||||
|
'permlevel': 1,
|
||||||
|
'role': u'Accounts User'
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocPerm
|
||||||
|
{
|
||||||
|
'doctype': u'DocPerm',
|
||||||
|
'match': u'customer_name',
|
||||||
|
'permlevel': 0,
|
||||||
|
'role': u'Customer'
|
||||||
},
|
},
|
||||||
|
|
||||||
# DocPerm
|
# DocPerm
|
||||||
{
|
{
|
||||||
'doctype': u'DocPerm',
|
'doctype': u'DocPerm',
|
||||||
'permlevel': 2,
|
'permlevel': 2,
|
||||||
'role': u'All'
|
'role': u'All',
|
||||||
|
'write': 1
|
||||||
},
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
@ -340,6 +384,7 @@
|
|||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'allow_on_submit': 1,
|
'allow_on_submit': 1,
|
||||||
|
'colour': u'White:FFF',
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
'fieldname': u'delivery_note_details',
|
'fieldname': u'delivery_note_details',
|
||||||
'fieldtype': u'Table',
|
'fieldtype': u'Table',
|
||||||
@ -352,6 +397,16 @@
|
|||||||
'print_hide': 0
|
'print_hide': 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'sales_bom_help',
|
||||||
|
'fieldtype': u'HTML',
|
||||||
|
'label': u'Sales BOM Help',
|
||||||
|
'permlevel': 0,
|
||||||
|
'print_hide': 1
|
||||||
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
# These values are common in all dictionaries
|
# These values are common in all dictionaries
|
||||||
{
|
{
|
||||||
'creation': '2012-04-13 11:56:35',
|
'creation': '2012-06-11 12:10:10',
|
||||||
'docstatus': 0,
|
'docstatus': 0,
|
||||||
'modified': '2012-05-09 12:55:23',
|
'modified': '2012-07-10 12:05:31',
|
||||||
'modified_by': u'Administrator',
|
'modified_by': u'Administrator',
|
||||||
'owner': u'Administrator'
|
'owner': u'Administrator'
|
||||||
},
|
},
|
||||||
@ -111,7 +111,7 @@
|
|||||||
'oldfieldname': u'warehouse',
|
'oldfieldname': u'warehouse',
|
||||||
'oldfieldtype': u'Link',
|
'oldfieldtype': u'Link',
|
||||||
'options': u'Warehouse',
|
'options': u'Warehouse',
|
||||||
'permlevel': 1
|
'permlevel': 0
|
||||||
},
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
|
|||||||
@ -51,19 +51,16 @@ class DocType:
|
|||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
|
|
||||||
|
|
||||||
# -----------------
|
def scrub_serial_nos(self, obj, table_name = ''):
|
||||||
# scrub serial nos
|
if not table_name:
|
||||||
# -----------------
|
table_name = obj.fname
|
||||||
def scrub_serial_nos(self, obj):
|
|
||||||
for d in getlist(obj.doclist, obj.fname):
|
for d in getlist(obj.doclist, table_name):
|
||||||
if d.serial_no:
|
if d.serial_no:
|
||||||
d.serial_no = d.serial_no.replace(',', '\n')
|
d.serial_no = d.serial_no.replace(',', '\n')
|
||||||
d.save()
|
d.save()
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# validate serial no warehouse
|
|
||||||
# -----------------------------
|
|
||||||
def validate_serial_no_warehouse(self, obj, fname):
|
def validate_serial_no_warehouse(self, obj, fname):
|
||||||
for d in getlist(obj.doclist, fname):
|
for d in getlist(obj.doclist, fname):
|
||||||
wh = d.warehouse or d.s_warehouse
|
wh = d.warehouse or d.s_warehouse
|
||||||
@ -80,10 +77,8 @@ class DocType:
|
|||||||
msgprint("Serial No : %s for Item : %s doesn't exists in Warehouse : %s" % (s, d.item_code, wh), raise_exception = 1)
|
msgprint("Serial No : %s for Item : %s doesn't exists in Warehouse : %s" % (s, d.item_code, wh), raise_exception = 1)
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------
|
|
||||||
# check whether serial no is required
|
|
||||||
# ------------------------------------
|
|
||||||
def validate_serial_no(self, obj, fname):
|
def validate_serial_no(self, obj, fname):
|
||||||
|
"""check whether serial no is required"""
|
||||||
for d in getlist(obj.doclist, fname):
|
for d in getlist(obj.doclist, fname):
|
||||||
is_stock_item = get_value('Item', d.item_code, 'is_stock_item')
|
is_stock_item = get_value('Item', d.item_code, 'is_stock_item')
|
||||||
ar_required = get_value('Item', d.item_code, 'has_serial_no')
|
ar_required = get_value('Item', d.item_code, 'has_serial_no')
|
||||||
@ -101,18 +96,10 @@ class DocType:
|
|||||||
msgprint("Rejected serial no is mandatory for rejected qty of item: "+ d.item_code, raise_exception = 1)
|
msgprint("Rejected serial no is mandatory for rejected qty of item: "+ d.item_code, raise_exception = 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -------------------
|
|
||||||
# get serial no list
|
|
||||||
# -------------------
|
|
||||||
def get_sr_no_list(self, sr_nos, qty = 0, item_code = ''):
|
def get_sr_no_list(self, sr_nos, qty = 0, item_code = ''):
|
||||||
return get_sr_no_list(sr_nos, qty, item_code)
|
return get_sr_no_list(sr_nos, qty, item_code)
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# set serial no values
|
|
||||||
# ---------------------
|
|
||||||
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec):
|
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec):
|
||||||
item_details = sql("select item_group, warranty_period from `tabItem` where name = '%s' and \
|
item_details = sql("select item_group, warranty_period from `tabItem` where name = '%s' and \
|
||||||
(ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) " %(d.item_code), as_dict=1)
|
(ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) " %(d.item_code), as_dict=1)
|
||||||
@ -143,9 +130,6 @@ class DocType:
|
|||||||
s.save(new_rec)
|
s.save(new_rec)
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------
|
|
||||||
# update serial no purchase details
|
|
||||||
# ----------------------------------
|
|
||||||
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = ''):
|
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = ''):
|
||||||
exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
|
exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
|
||||||
if is_submit:
|
if is_submit:
|
||||||
@ -168,9 +152,6 @@ class DocType:
|
|||||||
sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
|
sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------
|
|
||||||
# check whether serial no exists
|
|
||||||
# -------------------------------
|
|
||||||
def check_serial_no_exists(self, serial_no, item_code):
|
def check_serial_no_exists(self, serial_no, item_code):
|
||||||
chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
|
chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
|
||||||
if not chk:
|
if not chk:
|
||||||
@ -182,9 +163,7 @@ class DocType:
|
|||||||
elif chk and chk[0]['status'] == 'Delivered':
|
elif chk and chk[0]['status'] == 'Delivered':
|
||||||
msgprint("Serial No: %s of Item : %s is already delivered." % (serial_no, item_code), raise_exception = 1)
|
msgprint("Serial No: %s of Item : %s is already delivered." % (serial_no, item_code), raise_exception = 1)
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# set serial no values
|
|
||||||
# ---------------------
|
|
||||||
def set_delivery_serial_no_values(self, obj, serial_no):
|
def set_delivery_serial_no_values(self, obj, serial_no):
|
||||||
s = Document('Serial No', serial_no)
|
s = Document('Serial No', serial_no)
|
||||||
s.delivery_document_type = obj.doc.doctype
|
s.delivery_document_type = obj.doc.doctype
|
||||||
@ -203,9 +182,6 @@ class DocType:
|
|||||||
s.save()
|
s.save()
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------
|
|
||||||
# update serial no delivery details
|
|
||||||
# ----------------------------------
|
|
||||||
def update_serial_delivery_details(self, obj, d, serial_no, is_submit):
|
def update_serial_delivery_details(self, obj, d, serial_no, is_submit):
|
||||||
if is_submit:
|
if is_submit:
|
||||||
self.check_serial_no_exists(serial_no, d.item_code)
|
self.check_serial_no_exists(serial_no, d.item_code)
|
||||||
@ -214,9 +190,6 @@ class DocType:
|
|||||||
sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
|
sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
|
||||||
|
|
||||||
|
|
||||||
# ---------------------
|
|
||||||
# update serial record
|
|
||||||
# ---------------------
|
|
||||||
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
|
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
|
||||||
import datetime
|
import datetime
|
||||||
for d in getlist(obj.doclist, fname):
|
for d in getlist(obj.doclist, fname):
|
||||||
@ -235,11 +208,6 @@ class DocType:
|
|||||||
self.update_serial_purchase_details(obj, d, a, is_submit)
|
self.update_serial_purchase_details(obj, d, a, is_submit)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -------------
|
|
||||||
# update stock
|
|
||||||
# -------------
|
|
||||||
def update_stock(self, values, is_amended = 'No'):
|
def update_stock(self, values, is_amended = 'No'):
|
||||||
for v in values:
|
for v in values:
|
||||||
sle_id, serial_nos = '', ''
|
sle_id, serial_nos = '', ''
|
||||||
@ -261,9 +229,6 @@ class DocType:
|
|||||||
v["posting_date"], sle_id, v["posting_time"], '', v["is_cancelled"],v["voucher_type"],v["voucher_no"], is_amended)
|
v["posting_date"], sle_id, v["posting_time"], '', v["is_cancelled"],v["voucher_type"],v["voucher_no"], is_amended)
|
||||||
|
|
||||||
|
|
||||||
# -----------
|
|
||||||
# make entry
|
|
||||||
# -----------
|
|
||||||
def make_entry(self, args):
|
def make_entry(self, args):
|
||||||
sle = Document(doctype = 'Stock Ledger Entry')
|
sle = Document(doctype = 'Stock Ledger Entry')
|
||||||
for k in args.keys():
|
for k in args.keys():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user