Merge pull request #315 from mayur-patel/master
Added default for Employee doctype with help of Anand Doshi
diff --git a/accounts/__init__.py b/accounts/__init__.py
index 707203f..145ad6b 100644
--- a/accounts/__init__.py
+++ b/accounts/__init__.py
@@ -32,209 +32,3 @@
WHERE name=%s AND docstatus<2""", company)
if res: return res[0][0]
-
-@webnotes.whitelist()
-def get_new_jv_details():
- """
- Get details which will help create new jv on sales/purchase return
- """
- doclist = webnotes.form_dict.get('doclist')
- fiscal_year = webnotes.form_dict.get('fiscal_year')
- if not (isinstance(doclist, basestring) and isinstance(fiscal_year, basestring)): return
-
- import json
- doclist = json.loads(doclist)
- doc, children = doclist[0], doclist[1:]
-
- if doc.get('return_type')=='Sales Return':
- if doc.get('sales_invoice_no'):
- return get_invoice_details(doc, children, fiscal_year)
- elif doc.get('delivery_note_no'):
- return get_delivery_note_details(doc, children, fiscal_year)
-
- elif doc.get('purchase_receipt_no'):
- return get_purchase_receipt_details(doc, children, fiscal_year)
-
-
-def get_invoice_details(doc, children, fiscal_year):
- """
- Gets details from an invoice to make new jv
- Returns [{
- 'account': ,
- 'balance': ,
- 'debit': ,
- 'credit': ,
- 'against_invoice': ,
- 'against_payable':
- }, { ... }, ...]
- """
- if doc.get('return_type')=='Sales Return':
- obj = get_obj('Sales Invoice', doc.get('sales_invoice_no'), with_children=1)
- else:
- obj = get_obj('Purchase Invoice', doc.get('purchase_invoice_no'), with_children=1)
- if not obj.doc.docstatus==1: return
-
- # Build invoice account jv detail record
- invoice_rec = get_invoice_account_jv_record(doc, children, fiscal_year, obj)
-
- # Build item accountwise jv detail records
- item_accountwise_list = get_item_accountwise_jv_record(doc, children, fiscal_year, obj)
-
- return [invoice_rec] + item_accountwise_list
-
-
-def get_invoice_account_jv_record(doc, children, fiscal_year, obj):
- """
- Build customer/supplier account jv detail record
- """
- # Calculate total return amount
- total_amt = sum([(flt(ch.get('rate')) * flt(ch.get('returned_qty'))) for ch in children])
-
- ret = {}
-
- if doc.get('return_type')=='Sales Return':
- account = obj.doc.debit_to
- ret['against_invoice'] = doc.get('sales_invoice_no')
- ret['credit'] = total_amt
- else:
- account = obj.doc.credit_to
- ret['against_voucher'] = doc.get('purchase_invoice_no')
- ret['debit'] = total_amt
-
- ret.update({
- 'account': account,
- 'balance': get_balance_on(account, doc.get("return_date"))
- })
-
- return ret
-
-
-def get_item_accountwise_jv_record(doc, children, fiscal_year, obj):
- """
- Build item accountwise jv detail records
- """
- if doc.get('return_type')=='Sales Return':
- amt_field = 'debit'
- ac_field = 'income_account'
- else:
- amt_field = 'credit'
- ac_field = 'expense_head'
-
- inv_children = dict([[ic.fields.get('item_code'), ic] for ic in obj.doclist if ic.fields.get('item_code')])
-
- accwise_list = []
-
- for ch in children:
- inv_ch = inv_children.get(ch.get('item_code'))
- if not inv_ch: continue
-
- amount = flt(ch.get('rate')) * flt(ch.get('returned_qty'))
-
- accounts = [[jvd['account'], jvd['cost_center']] for jvd in accwise_list]
-
- if [inv_ch.fields.get(ac_field), inv_ch.fields.get('cost_center')] not in accounts:
- rec = {
- 'account': inv_ch.fields.get(ac_field),
- 'cost_center': inv_ch.fields.get('cost_center'),
- 'balance': get_balance_on(inv_ch.fields.get(ac_field),
- doc.get("return_date"))
- }
- rec[amt_field] = amount
- accwise_list.append(rec)
- else:
- rec = accwise_list[accounts.index([inv_ch.fields.get(ac_field), inv_ch.fields.get('cost_center')])]
- rec[amt_field] = rec[amt_field] + amount
-
- return accwise_list
-
-
-def get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list):
- """
- Get invoice details and make jv detail records
- """
- for inv in inv_list:
- if not inv[0]: continue
-
- if doc.get('return_type')=='Sales Return':
- doc['sales_invoice_no'] = inv[0]
- else:
- doc['purchase_invoice_no'] = inv[0]
-
- jv_details = get_invoice_details(doc, children, fiscal_year)
-
- if jv_details and len(jv_details)>1: jv_details_list.extend(jv_details)
-
- return jv_details_list
-
-
-def get_prev_doc_list(obj, prev_doctype):
- """
- Returns a list of previous doc's names
- """
- prevdoc_list = []
- for ch in obj.doclist:
- if ch.fields.get('prevdoc_docname') and ch.fields.get('prevdoc_doctype')==prev_doctype:
- prevdoc_list.append(ch.fields.get('prevdoc_docname'))
- return prevdoc_list
-
-
-def get_inv_list(table, field, value):
- """
- Returns invoice list
- """
- if isinstance(value, basestring):
- return webnotes.conn.sql("""\
- SELECT DISTINCT parent FROM `%s`
- WHERE %s='%s' AND docstatus=1""" % (table, field, value))
- elif isinstance(value, list):
- return webnotes.conn.sql("""\
- SELECT DISTINCT parent FROM `%s`
- WHERE %s IN ("%s") AND docstatus=1""" % (table, field, '", "'.join(value)))
- else:
- return []
-
-
-def get_delivery_note_details(doc, children, fiscal_year):
- """
- Gets sales invoice numbers from delivery note details
- and returns detail records for jv
- """
- jv_details_list = []
-
- dn_obj = get_obj('Delivery Note', doc['delivery_note_no'], with_children=1)
-
- inv_list = get_inv_list('tabSales Invoice Item', 'delivery_note', doc['delivery_note_no'])
-
- if inv_list:
- jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list)
-
- if not (inv_list and jv_details_list):
- so_list = get_prev_doc_list(dn_obj, 'Sales Order')
- inv_list = get_inv_list('tabSales Invoice Item', 'sales_order', so_list)
- if inv_list:
- jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list)
-
- return jv_details_list
-
-
-def get_purchase_receipt_details(doc, children, fiscal_year):
- """
- Gets purchase invoice numbers from purchase receipt details
- and returns detail records for jv
- """
- jv_details_list = []
-
- pr_obj = get_obj('Purchase Receipt', doc['purchase_receipt_no'], with_children=1)
-
- inv_list = get_inv_list('tabPurchase Invoice Item', 'purchase_receipt', doc['purchase_receipt_no'])
-
- if inv_list:
- jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list)
-
- if not (inv_list and jv_details_list):
- po_list = get_prev_doc_list(pr_obj, 'Purchase Order')
- inv_list = get_inv_list('tabPurchase Invoice Item', 'purchase_order', po_list)
- if inv_list:
- jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list)
-
- return jv_details_list
diff --git a/accounts/doctype/account/account.py b/accounts/doctype/account/account.py
index 08bf80f..3cd131f 100644
--- a/accounts/doctype/account/account.py
+++ b/accounts/doctype/account/account.py
@@ -207,4 +207,4 @@
where group_or_ledger = 'Group' and docstatus != 2 and company = %s
and %s like %s order by name limit %s, %s""" %
("%s", searchfield, "%s", "%s", "%s"),
- (filters["company"], "%%%s%%" % txt, start, page_len), as_list=1)
+ (filters["company"], "%%%s%%" % txt, start, page_len), as_list=1)
\ No newline at end of file
diff --git a/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.txt b/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.txt
index 1b8b991..d814ad8 100644
--- a/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.txt
+++ b/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:05",
+ "creation": "2013-02-22 01:27:37",
"docstatus": 0,
- "modified": "2013-01-29 16:27:50",
+ "modified": "2013-03-07 07:03:18",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/accounts/doctype/budget_detail/budget_detail.txt b/accounts/doctype/budget_detail/budget_detail.txt
index b2b312c..3feb6f7 100644
--- a/accounts/doctype/budget_detail/budget_detail.txt
+++ b/accounts/doctype/budget_detail/budget_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:05",
+ "creation": "2013-02-22 01:27:37",
"docstatus": 0,
- "modified": "2013-01-29 16:28:16",
+ "modified": "2013-03-07 07:03:19",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt b/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt
index 0f11876..ff5d8fd 100644
--- a/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt
+++ b/accounts/doctype/budget_distribution_detail/budget_distribution_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:05",
+ "creation": "2013-02-22 01:27:38",
"docstatus": 0,
- "modified": "2013-01-22 14:41:34",
+ "modified": "2013-03-07 07:03:19",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/accounts/doctype/c_form_invoice_detail/c_form_invoice_detail.txt b/accounts/doctype/c_form_invoice_detail/c_form_invoice_detail.txt
index f9b7372..ba247d3 100644
--- a/accounts/doctype/c_form_invoice_detail/c_form_invoice_detail.txt
+++ b/accounts/doctype/c_form_invoice_detail/c_form_invoice_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:06",
+ "creation": "2013-02-22 01:27:38",
"docstatus": 0,
- "modified": "2013-01-29 16:27:50",
+ "modified": "2013-03-07 07:03:19",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -30,6 +30,7 @@
"fieldtype": "Link",
"label": "Invoice No",
"options": "Sales Invoice",
+ "print_width": "160px",
"width": "160px"
},
{
@@ -37,6 +38,7 @@
"fieldname": "invoice_date",
"fieldtype": "Date",
"label": "Invoice Date",
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
},
@@ -46,6 +48,7 @@
"fieldtype": "Link",
"label": "Territory",
"options": "Territory",
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
},
@@ -55,6 +58,7 @@
"fieldtype": "Currency",
"label": "Net Total",
"options": "Company:company:default_currency",
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
},
@@ -64,6 +68,7 @@
"fieldtype": "Currency",
"label": "Grand Total",
"options": "Company:company:default_currency",
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
}
diff --git a/accounts/doctype/fiscal_year/fiscal_year.txt b/accounts/doctype/fiscal_year/fiscal_year.txt
index 18f20dd..935b76f 100644
--- a/accounts/doctype/fiscal_year/fiscal_year.txt
+++ b/accounts/doctype/fiscal_year/fiscal_year.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:06",
+ "creation": "2013-01-22 16:50:25",
"docstatus": 0,
- "modified": "2013-01-22 14:46:59",
+ "modified": "2013-03-13 12:29:40",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -23,7 +23,6 @@
"permlevel": 0
},
{
- "amend": 0,
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
@@ -43,22 +42,6 @@
"name": "Fiscal Year"
},
{
- "doctype": "DocField",
- "fieldname": "year_details",
- "fieldtype": "Section Break",
- "label": "Fiscal Year Details",
- "oldfieldtype": "Section Break"
- },
- {
- "doctype": "DocField",
- "fieldname": "trash_reason",
- "fieldtype": "Small Text",
- "label": "Trash Reason",
- "oldfieldname": "trash_reason",
- "oldfieldtype": "Small Text",
- "read_only": 1
- },
- {
"description": "For e.g. 2012, 2012-13",
"doctype": "DocField",
"fieldname": "year",
@@ -73,6 +56,7 @@
"fieldname": "year_start_date",
"fieldtype": "Date",
"label": "Year Start Date",
+ "no_copy": 1,
"oldfieldname": "year_start_date",
"oldfieldtype": "Date",
"reqd": 1
@@ -84,6 +68,7 @@
"fieldname": "is_fiscal_year_closed",
"fieldtype": "Select",
"label": "Year Closed",
+ "no_copy": 1,
"oldfieldname": "is_fiscal_year_closed",
"oldfieldtype": "Select",
"options": "\nNo\nYes",
diff --git a/accounts/doctype/fiscal_year/test_fiscal_year.py b/accounts/doctype/fiscal_year/test_fiscal_year.py
index e031a19..b209b39 100644
--- a/accounts/doctype/fiscal_year/test_fiscal_year.py
+++ b/accounts/doctype/fiscal_year/test_fiscal_year.py
@@ -10,5 +10,15 @@
"doctype": "Fiscal Year",
"year": "_Test Fiscal Year 2014",
"year_start_date": "2014-01-01"
- }]
+ }],
+ [{
+ "doctype": "Fiscal Year",
+ "year": "_Test Fiscal Year 2015",
+ "year_start_date": "2015-01-01"
+ }],
+ [{
+ "doctype": "Fiscal Year",
+ "year": "_Test Fiscal Year 2016",
+ "year_start_date": "2016-01-01"
+ }],
]
\ No newline at end of file
diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py
index 2acf08e..f4bd55c 100644
--- a/accounts/doctype/journal_voucher/journal_voucher.py
+++ b/accounts/doctype/journal_voucher/journal_voucher.py
@@ -63,6 +63,9 @@
self.make_gl_entries()
def on_cancel(self):
+ from accounts.utils import remove_against_link_from_jv
+ remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_jv")
+
self.make_gl_entries(cancel=1)
def validate_debit_credit(self):
diff --git a/accounts/doctype/journal_voucher/test_journal_voucher.py b/accounts/doctype/journal_voucher/test_journal_voucher.py
index bb846d1..7cfeb59 100644
--- a/accounts/doctype/journal_voucher/test_journal_voucher.py
+++ b/accounts/doctype/journal_voucher/test_journal_voucher.py
@@ -19,8 +19,34 @@
import unittest
import webnotes
-test_records = [[
- {
+class TestJournalVoucher(unittest.TestCase):
+ def test_journal_voucher_with_against_jv(self):
+ jv_invoice = webnotes.bean(copy=test_records[2])
+ jv_invoice.insert()
+ jv_invoice.submit()
+
+ self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_jv=%s""", jv_invoice.doc.name))
+
+ jv_payment = webnotes.bean(copy=test_records[0])
+ jv_payment.doclist[1].against_jv = jv_invoice.doc.name
+ jv_payment.insert()
+ jv_payment.submit()
+
+ self.assertTrue(webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_jv=%s""", jv_invoice.doc.name))
+
+ self.assertTrue(webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_jv=%s and credit=400""", jv_invoice.doc.name))
+
+ # cancel jv_invoice
+ jv_invoice.cancel()
+
+ self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_jv=%s""", jv_invoice.doc.name))
+
+test_records = [
+ [{
"company": "_Test Company",
"doctype": "Journal Voucher",
"fiscal_year": "_Test Fiscal Year 2013",
@@ -44,8 +70,59 @@
"debit": 400.0,
"credit": 0.0,
"parentfield": "entries"
- }
-]]
+ }],
+ [{
+ "company": "_Test Company",
+ "doctype": "Journal Voucher",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "naming_series": "_T-Journal Voucher-",
+ "posting_date": "2013-02-14",
+ "user_remark": "test",
+ "voucher_type": "Bank Voucher",
+ "cheque_no": "33",
+ "cheque_date": "2013-02-14"
+ },
+ {
+ "account": "_Test Supplier - _TC",
+ "doctype": "Journal Voucher Detail",
+ "credit": 0.0,
+ "debit": 400.0,
+ "parentfield": "entries"
+ },
+ {
+ "account": "_Test Account Bank Account - _TC",
+ "doctype": "Journal Voucher Detail",
+ "debit": 0.0,
+ "credit": 400.0,
+ "parentfield": "entries"
+ }],
+ [{
+ "company": "_Test Company",
+ "doctype": "Journal Voucher",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "naming_series": "_T-Journal Voucher-",
+ "posting_date": "2013-02-14",
+ "user_remark": "test",
+ "voucher_type": "Bank Voucher",
+ "cheque_no": "33",
+ "cheque_date": "2013-02-14"
+ },
+ {
+ "account": "_Test Customer - _TC",
+ "doctype": "Journal Voucher Detail",
+ "credit": 0.0,
+ "debit": 400.0,
+ "parentfield": "entries"
+ },
+ {
+ "account": "Sales - _TC",
+ "doctype": "Journal Voucher Detail",
+ "credit": 400.0,
+ "debit": 0.0,
+ "parentfield": "entries",
+ "cost_center": "_Test Cost Center - _TC"
+ }],
+]
diff --git a/accounts/doctype/journal_voucher_detail/journal_voucher_detail.txt b/accounts/doctype/journal_voucher_detail/journal_voucher_detail.txt
index 245ddf1..ac30346 100644
--- a/accounts/doctype/journal_voucher_detail/journal_voucher_detail.txt
+++ b/accounts/doctype/journal_voucher_detail/journal_voucher_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:06",
+ "creation": "2013-02-22 01:27:39",
"docstatus": 0,
- "modified": "2013-01-29 16:27:50",
+ "modified": "2013-03-07 07:03:23",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -34,6 +34,7 @@
"oldfieldname": "account",
"oldfieldtype": "Link",
"options": "Account",
+ "print_width": "250px",
"reqd": 1,
"search_index": 1,
"width": "250px"
@@ -65,6 +66,7 @@
"oldfieldname": "cost_center",
"oldfieldtype": "Link",
"options": "Cost Center",
+ "print_width": "180px",
"search_index": 0,
"width": "180px"
},
diff --git a/accounts/doctype/multi_ledger_report_detail/multi_ledger_report_detail.txt b/accounts/doctype/multi_ledger_report_detail/multi_ledger_report_detail.txt
index df91e1c..46563dd 100755
--- a/accounts/doctype/multi_ledger_report_detail/multi_ledger_report_detail.txt
+++ b/accounts/doctype/multi_ledger_report_detail/multi_ledger_report_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:35:44",
+ "creation": "2013-02-22 01:27:39",
"docstatus": 0,
- "modified": "2012-03-27 14:35:44",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Accounts",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 3
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -26,6 +23,7 @@
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
+ "print_width": "300px",
"reqd": 1,
"width": "300px"
},
diff --git a/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.txt b/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.txt
index 5fcb606..1908101 100644
--- a/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.txt
+++ b/accounts/doctype/payment_to_invoice_matching_tool_detail/payment_to_invoice_matching_tool_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:07",
+ "creation": "2013-02-22 01:27:39",
"docstatus": 0,
- "modified": "2013-01-29 16:27:50",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/accounts/doctype/pos_setting/test_pos_setting.py b/accounts/doctype/pos_setting/test_pos_setting.py
new file mode 100644
index 0000000..2c45c4d
--- /dev/null
+++ b/accounts/doctype/pos_setting/test_pos_setting.py
@@ -0,0 +1,14 @@
+test_records = [
+ [{
+ "doctype": "POS Setting",
+ "name": "_Test POS Setting",
+ "currency": "INR",
+ "conversion_rate": 1.0,
+ "price_list_name": "_Test Price List",
+ "company": "_Test Company",
+ "warehouse": "_Test Warehouse",
+ "cash_bank_account": "_Test Account Bank Account - _TC",
+ "income_account": "Sales - _TC",
+ "cost_center": "_Test Cost Center - _TC",
+ }]
+]
\ No newline at end of file
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.js b/accounts/doctype/purchase_invoice/purchase_invoice.js
index f4a2e68..4a1cbba 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -238,8 +238,11 @@
refresh_field('entries');
}
-cur_frm.fields_dict['entries'].grid.get_field("cost_center").get_query = function(doc) {
- return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.docstatus != 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
+cur_frm.fields_dict["entries"].grid.get_field("cost_center").get_query = function(doc) {
+ return {
+ query: "accounts.utils.get_cost_center_list",
+ filters: { company_name: doc.company}
+ }
}
cur_frm.cscript.cost_center = function(doc, cdt, cdn){
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py
index 7722c98..f535d56 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -444,6 +444,9 @@
# item gl entries
stock_item_and_auto_inventory_accounting = False
+ if auto_inventory_accounting:
+ stock_acocunt = self.get_default_account("stock_received_but_not_billed")
+
for item in self.doclist.get({"parentfield": "entries"}):
if auto_inventory_accounting and item.item_code in self.stock_items:
if flt(item.valuation_rate):
@@ -455,7 +458,7 @@
gl_entries.append(
self.get_gl_dict({
- "account": "Stock Received But Not Billed - %s" % (self.company_abbr,),
+ "account": stock_acocunt,
"against": self.doc.credit_to,
"debit": flt(item.valuation_rate) * flt(item.conversion_factor) \
* flt(item.qty),
@@ -480,7 +483,7 @@
# this will balance out valuation amount included in cost of goods sold
gl_entries.append(
self.get_gl_dict({
- "account": "Expenses Included In Valuation - %s" % (self.company_abbr,),
+ "account": self.get_default_account("expenses_included_in_valuation"),
"cost_center": "Auto Inventory Accounting - %s" % self.company_abbr,
"against": self.doc.credit_to,
"credit": valuation_tax,
@@ -504,18 +507,13 @@
if gl_entries:
make_gl_entries(gl_entries, cancel=is_cancel)
- def check_next_docstatus(self):
- submit_jv = sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_voucher = '%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_cancel(self):
- self.check_next_docstatus()
+ from accounts.utils import remove_against_link_from_jv
+ remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_voucher")
self.make_gl_entries(is_cancel=1)
get_obj(dt = 'Purchase Common').update_prevdoc_detail(self, is_submit = 0)
-
+
def on_update(self):
pass
diff --git a/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index b9f7ec9..6d9cfca 100644
--- a/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -115,6 +115,42 @@
for i, item in enumerate(wrapper.doclist.get({"parentfield": "entries"})):
self.assertEqual(item.item_code, expected_values[i][0])
self.assertEqual(item.item_tax_amount, expected_values[i][1])
+
+ def test_purchase_invoice_with_advance(self):
+ from accounts.doctype.journal_voucher.test_journal_voucher \
+ import test_records as jv_test_records
+
+ jv = webnotes.bean(copy=jv_test_records[1])
+ jv.insert()
+ jv.submit()
+
+ pi = webnotes.bean(copy=test_records[0])
+ pi.doclist.append({
+ "doctype": "Purchase Invoice Advance",
+ "parentfield": "advance_allocation_details",
+ "journal_voucher": jv.doc.name,
+ "jv_detail_no": jv.doclist[1].name,
+ "advance_amount": 400,
+ "allocated_amount": 300,
+ "remarks": jv.doc.remark
+ })
+ pi.run_method("calculate_taxes_and_totals")
+ pi.insert()
+ pi.submit()
+ pi.load_from_db()
+
+ self.assertTrue(webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_voucher=%s""", pi.doc.name))
+
+ self.assertTrue(webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_voucher=%s and debit=300""", pi.doc.name))
+
+ self.assertEqual(pi.doc.outstanding_amount, 1212.30)
+
+ pi.cancel()
+
+ self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_voucher=%s""", pi.doc.name))
test_records = [
[
diff --git a/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.txt b/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.txt
index dadf28a..6b31684 100644
--- a/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.txt
+++ b/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:08",
+ "creation": "2013-03-08 15:36:46",
"docstatus": 0,
- "modified": "2013-01-29 16:27:50",
+ "modified": "2013-03-20 16:52:12",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -33,18 +33,20 @@
"oldfieldname": "journal_voucher",
"oldfieldtype": "Link",
"options": "Journal Voucher",
+ "print_width": "180px",
"read_only": 1,
"width": "180px"
},
{
"doctype": "DocField",
"fieldname": "jv_detail_no",
- "fieldtype": "Date",
+ "fieldtype": "Data",
"hidden": 1,
"label": "Journal Voucher Detail No",
"oldfieldname": "jv_detail_no",
"oldfieldtype": "Date",
"print_hide": 1,
+ "print_width": "80px",
"read_only": 1,
"width": "80px"
},
@@ -56,6 +58,7 @@
"oldfieldname": "advance_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -67,6 +70,7 @@
"oldfieldname": "allocated_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
+ "print_width": "100px",
"width": "100px"
},
{
@@ -76,6 +80,7 @@
"label": "Remarks",
"oldfieldname": "remarks",
"oldfieldtype": "Small Text",
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
}
diff --git a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
index 553041e..b8d9a1d 100755
--- a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
+++ b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-11 10:54:51",
+ "creation": "2013-02-27 13:45:00",
"docstatus": 0,
- "modified": "2013-02-27 18:10:04",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt b/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt
index 6067afb..b593b81 100644
--- a/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt
+++ b/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt
@@ -1,10 +1,10 @@
[
{
- "creation": "2013-01-10 16:34:08",
+ "creation": "2013-03-08 15:36:47",
"docstatus": 0,
- "modified": "2013-01-29 16:27:50",
+ "modified": "2013-03-22 16:45:28",
"modified_by": "Administrator",
- "owner": "wasim@webnotestech.com"
+ "owner": "Administrator"
},
{
"autoname": "PVTD.######",
@@ -27,6 +27,17 @@
"name": "Purchase Taxes and Charges"
},
{
+ "default": "Valuation and Total",
+ "doctype": "DocField",
+ "fieldname": "category",
+ "fieldtype": "Select",
+ "label": "Consider Tax or Charge for",
+ "oldfieldname": "category",
+ "oldfieldtype": "Select",
+ "options": "Valuation and Total\nValuation\nTotal",
+ "reqd": 1
+ },
+ {
"doctype": "DocField",
"fieldname": "charge_type",
"fieldtype": "Select",
@@ -62,6 +73,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Small Text",
+ "print_width": "300px",
"reqd": 1,
"width": "300px"
},
@@ -105,17 +117,6 @@
"oldfieldtype": "Data"
},
{
- "default": "Valuation and Total",
- "doctype": "DocField",
- "fieldname": "category",
- "fieldtype": "Select",
- "label": "Consider Tax or Charge for",
- "oldfieldname": "category",
- "oldfieldtype": "Select",
- "options": "Valuation and Total\nValuation\nTotal",
- "reqd": 1
- },
- {
"default": "Add",
"doctype": "DocField",
"fieldname": "add_deduct_tax",
diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js
index a24e256..5cc09a0 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/accounts/doctype/sales_invoice/sales_invoice.js
@@ -271,8 +271,6 @@
if (doc.is_opening == 'Yes') unhide_field('aging_date');
}
-/* **************************** TRIGGERS ********************************** */
-
// Get Items based on SO or DN Selected
cur_frm.cscript.get_items = function(doc, dt, dn) {
var callback = function(r,rt) {
@@ -371,6 +369,18 @@
return 'SELECT tabAccount.name FROM tabAccount WHERE (tabAccount.debit_or_credit="Credit" OR tabAccount.account_type = "Income Account") AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"';
})
+// expense account
+cur_frm.fields_dict['entries'].grid.get_field('expense_account').get_query = function(doc) {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": {
+ "is_pl_account": "Yes",
+ "debit_or_credit": "Debit",
+ "company": doc.company
+ }
+ }
+}
+
// warehouse in detail table
//----------------------------
cur_frm.fields_dict['entries'].grid.get_field('warehouse').get_query= function(doc, cdt, cdn) {
@@ -380,8 +390,11 @@
// Cost Center in Details Table
// -----------------------------
-cur_frm.fields_dict.entries.grid.get_field("cost_center").get_query = function(doc) {
- return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
+cur_frm.fields_dict["entries"].grid.get_field("cost_center").get_query = function(doc) {
+ return {
+ query: "accounts.utils.get_cost_center_list",
+ filters: { company_name: doc.company}
+ }
}
// Sales Order
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index 47e3195..9b5c80c 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -8,7 +8,7 @@
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
@@ -17,7 +17,9 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import add_days, cint, cstr, date_diff, flt, getdate, nowdate
+from webnotes.utils import add_days, cint, cstr, date_diff, flt, getdate, nowdate, \
+ get_first_day, get_last_day
+
from webnotes.utils.email_lib import sendmail
from webnotes.utils import comma_and
from webnotes.model.doc import make_autoname
@@ -45,6 +47,7 @@
def validate(self):
super(DocType, self).validate()
+ self.validate_posting_time()
self.so_dn_required()
self.validate_proj_cust()
sales_com_obj = get_obj('Sales Common')
@@ -95,7 +98,8 @@
if not self.doc.recurring_id:
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype,
self.doc.company, self.doc.grand_total, self)
-
+
+ self.set_buying_amount()
self.check_prev_docstatus()
get_obj("Sales Common").update_prevdoc_detail(1,self)
@@ -123,11 +127,14 @@
sales_com_obj = get_obj(dt = 'Sales Common')
sales_com_obj.check_stop_sales_order(self)
- self.check_next_docstatus()
+
+ from accounts.utils import remove_against_link_from_jv
+ remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_invoice")
+
sales_com_obj.update_prevdoc_detail(0, self)
- self.make_gl_entries(is_cancel=1)
-
+ self.make_gl_entries()
+
def on_update_after_submit(self):
self.validate_recurring_invoice()
self.convert_to_recurring()
@@ -395,8 +402,7 @@
if lst:
from accounts.utils import reconcile_against_document
reconcile_against_document(lst)
-
-
+
def validate_customer(self):
""" Validate customer name with SO and DN"""
for d in getlist(self.doclist,'entries'):
@@ -537,8 +543,7 @@
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
+ msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.", raise_exception=True)
elif not ps[0][1]:
msgprint("Please enter warehouse in POS Setting")
else:
@@ -619,8 +624,7 @@
'is_cancelled' : (update_stock==1) and 'No' or 'Yes',
'batch_no' : cstr(d['batch_no']),
'serial_no' : d['serial_no']
- })
-
+ })
def update_stock_ledger(self, update_stock):
self.values = []
@@ -635,10 +639,9 @@
# Reduce actual qty from warehouse
self.make_sl_entry( d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
-
+
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
-
-
+
def get_actual_qty(self,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)
@@ -648,14 +651,29 @@
return ret
- def make_gl_entries(self, is_cancel=0):
- from accounts.general_ledger import make_gl_entries
- gl_entries = []
- auto_inventory_accounting = webnotes.conn.get_value("Global Defaults", None,
- "automatic_inventory_accounting")
- abbr = self.get_company_abbr()
+ def make_gl_entries(self):
+ from accounts.general_ledger import make_gl_entries, merge_similar_entries
- # parent's gl entry
+ gl_entries = []
+
+ self.make_customer_gl_entry(gl_entries)
+
+ self.make_tax_gl_entries(gl_entries)
+
+ self.make_item_gl_entries(gl_entries)
+
+ # merge gl entries before adding pos entries
+ gl_entries = merge_similar_entries(gl_entries)
+
+ self.make_pos_gl_entries(gl_entries)
+
+ update_outstanding = cint(self.doc.is_pos) and self.doc.write_off_account and 'No' or 'Yes'
+
+ if gl_entries:
+ make_gl_entries(gl_entries, cancel=(self.doc.docstatus == 2),
+ update_outstanding=update_outstanding, merge_entries=False)
+
+ def make_customer_gl_entry(self, gl_entries):
if self.doc.grand_total:
gl_entries.append(
self.get_gl_dict({
@@ -665,10 +683,10 @@
"remarks": self.doc.remarks,
"against_voucher": self.doc.name,
"against_voucher_type": self.doc.doctype,
- }, is_cancel)
+ })
)
-
- # tax table gl entries
+
+ def make_tax_gl_entries(self, gl_entries):
for tax in self.doclist.get({"parentfield": "other_charges"}):
if flt(tax.tax_amount):
gl_entries.append(
@@ -678,12 +696,12 @@
"credit": flt(tax.tax_amount),
"remarks": self.doc.remarks,
"cost_center": tax.cost_center_other_charges
- }, is_cancel)
+ })
)
-
- # item gl entries
- for item in getlist(self.doclist, 'entries'):
- # income account gl entries
+
+ def make_item_gl_entries(self, gl_entries):
+ # income account gl entries
+ for item in self.doclist.get({"parentfield": "entries"}):
if flt(item.amount):
gl_entries.append(
self.get_gl_dict({
@@ -692,35 +710,21 @@
"credit": item.amount,
"remarks": self.doc.remarks,
"cost_center": item.cost_center
- }, is_cancel)
+ })
)
- # if auto inventory accounting enabled and stock item,
- # then do stock related gl entries
- if auto_inventory_accounting and item.delivery_note and \
- webnotes.conn.get_value("Item", item.item_code, "is_stock_item")=="Yes":
- # to-do
- purchase_rate = webnotes.conn.get_value("Delivery Note Item",
- item.dn_detail, "purchase_rate")
- valuation_amount = purchase_rate * item.qty
- # expense account gl entries
- if flt(valuation_amount):
- gl_entries.append(
- self.get_gl_dict({
- "account": item.expense_account,
- "against": "Stock Delivered But Not Billed - %s" % (abbr,),
- "debit": valuation_amount,
- "remarks": self.doc.remarks or "Accounting Entry for Stock"
- }, is_cancel)
- )
- gl_entries.append(
- self.get_gl_dict({
- "account": "Stock Delivered But Not Billed - %s" % (abbr,),
- "against": item.expense_account,
- "credit": valuation_amount,
- "remarks": self.doc.remarks or "Accounting Entry for Stock"
- }, is_cancel)
- )
- if self.doc.is_pos and self.doc.cash_bank_account and self.doc.paid_amount:
+
+ # expense account gl entries
+ if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) \
+ and cint(self.doc.is_pos) and cint(self.doc.update_stock):
+
+ for item in self.doclist.get({"parentfield": "entries"}):
+ self.check_expense_account(item)
+
+ gl_entries += self.get_gl_entries_for_stock(item.expense_account,
+ -1*item.buying_amount, cost_center=item.cost_center)
+
+ def make_pos_gl_entries(self, gl_entries):
+ if cint(self.doc.is_pos) and self.doc.cash_bank_account and self.doc.paid_amount:
# POS, make payment entries
gl_entries.append(
self.get_gl_dict({
@@ -730,7 +734,7 @@
"remarks": self.doc.remarks,
"against_voucher": self.doc.name,
"against_voucher_type": self.doc.doctype,
- }, is_cancel)
+ })
)
gl_entries.append(
self.get_gl_dict({
@@ -738,7 +742,7 @@
"against": self.doc.debit_to,
"debit": self.doc.paid_amount,
"remarks": self.doc.remarks,
- }, is_cancel)
+ })
)
# write off entries, applicable if only pos
if self.doc.write_off_account and self.doc.write_off_amount:
@@ -750,7 +754,7 @@
"remarks": self.doc.remarks,
"against_voucher": self.doc.name,
"against_voucher_type": self.doc.doctype,
- }, is_cancel)
+ })
)
gl_entries.append(
self.get_gl_dict({
@@ -759,30 +763,17 @@
"debit": self.doc.write_off_amount,
"remarks": self.doc.remarks,
"cost_center": self.doc.write_off_cost_center
- }, is_cancel)
+ })
)
-
-
- update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
- merge_entries=cint(self.doc.is_pos)!=1 and 1 or 0
- if gl_entries:
- make_gl_entries(gl_entries, cancel=is_cancel,
- update_outstanding=update_outstanding, merge_entries=merge_entries)
-
+
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))
+ 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."
-
@property
def meta(self):
if not hasattr(self, "_meta"):
@@ -842,25 +833,18 @@
next_date = get_next_date(self.doc.posting_date,
month_map[self.doc.recurring_type], cint(self.doc.repeat_on_day_of_month))
+
webnotes.conn.set(self.doc, 'next_date', next_date)
def get_next_date(dt, mcount, day=None):
- import datetime
- month = getdate(dt).month + mcount
- year = getdate(dt).year
- if not day:
- day = getdate(dt).day
- if month > 12:
- month, year = month-12, year+1
- try:
- next_month_date = datetime.date(year, month, day)
- except:
- import calendar
- last_day = calendar.monthrange(year, month)[1]
- next_month_date = datetime.date(year, month, last_day)
- return next_month_date.strftime("%Y-%m-%d")
-
-def manage_recurring_invoices(next_date=None):
+ dt = getdate(dt)
+
+ from dateutil.relativedelta import relativedelta
+ dt += relativedelta(months=mcount, day=day)
+
+ return dt
+
+def manage_recurring_invoices(next_date=None, commit=True):
"""
Create recurring invoices on specific date by copying the original one
and notify the concerned people
@@ -880,19 +864,22 @@
ref_wrapper = webnotes.bean('Sales Invoice', ref_invoice)
new_invoice_wrapper = make_new_invoice(ref_wrapper, next_date)
send_notification(new_invoice_wrapper)
- webnotes.conn.commit()
+ if commit:
+ webnotes.conn.commit()
except:
- webnotes.conn.rollback()
+ if commit:
+ webnotes.conn.rollback()
- webnotes.conn.begin()
- webnotes.conn.sql("update `tabSales Invoice` set \
- convert_into_recurring_invoice = 0 where name = %s", ref_invoice)
- notify_errors(ref_invoice, ref_wrapper.doc.owner)
- webnotes.conn.commit()
+ webnotes.conn.begin()
+ webnotes.conn.sql("update `tabSales Invoice` set \
+ convert_into_recurring_invoice = 0 where name = %s", ref_invoice)
+ notify_errors(ref_invoice, ref_wrapper.doc.owner)
+ webnotes.conn.commit()
exception_list.append(webnotes.getTraceback())
finally:
- webnotes.conn.begin()
+ if commit:
+ webnotes.conn.begin()
if exception_list:
exception_message = "\n\n".join([cstr(d) for d in exception_list])
@@ -904,19 +891,27 @@
new_invoice = clone(ref_wrapper)
mcount = month_map[ref_wrapper.doc.recurring_type]
-
+
+ invoice_period_from_date = get_next_date(ref_wrapper.doc.invoice_period_from_date, mcount)
+
+ # get last day of the month to maintain period if the from date is first day of its own month
+ # and to date is the last day of its own month
+ if (cstr(get_first_day(ref_wrapper.doc.invoice_period_from_date)) == \
+ cstr(ref_wrapper.doc.invoice_period_from_date)) and \
+ (cstr(get_last_day(ref_wrapper.doc.invoice_period_to_date)) == \
+ cstr(ref_wrapper.doc.invoice_period_to_date)):
+ invoice_period_to_date = get_last_day(get_next_date(ref_wrapper.doc.invoice_period_to_date,
+ mcount))
+ else:
+ invoice_period_to_date = get_next_date(ref_wrapper.doc.invoice_period_to_date, mcount)
+
new_invoice.doc.fields.update({
"posting_date": posting_date,
"aging_date": posting_date,
-
"due_date": add_days(posting_date, cint(date_diff(ref_wrapper.doc.due_date,
ref_wrapper.doc.posting_date))),
-
- "invoice_period_from_date": \
- get_next_date(ref_wrapper.doc.invoice_period_from_date, mcount),
-
- "invoice_period_to_date": \
- get_next_date(ref_wrapper.doc.invoice_period_to_date, mcount),
+ "invoice_period_from_date": invoice_period_from_date,
+ "invoice_period_to_date": invoice_period_to_date,
"fiscal_year": get_fiscal_year(posting_date)[0],
"owner": ref_wrapper.doc.owner,
})
diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt
index c7c8fba..462565c 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-29 17:54:09",
+ "creation": "2013-03-20 17:01:58",
"docstatus": 0,
- "modified": "2013-01-29 18:22:52",
+ "modified": "2013-03-20 19:17:38",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -77,7 +77,6 @@
"print_hide": 1
},
{
- "default": "1",
"depends_on": "eval:doc.is_pos==1",
"doctype": "DocField",
"fieldname": "update_stock",
@@ -1094,7 +1093,7 @@
"description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc ",
"doctype": "DocField",
"fieldname": "repeat_on_day_of_month",
- "fieldtype": "Data",
+ "fieldtype": "Int",
"label": "Repeat on Day of Month",
"no_copy": 1,
"print_hide": 1
diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py
index fb290d2..7aa0c27 100644
--- a/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -38,72 +38,490 @@
si.insert()
si.submit()
- self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001", "status"),
- "Billed")
+ self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001",
+ "status"), "Billed")
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
"Billed")
si.cancel()
- self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001", "status"),
- "Submitted")
+ self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001",
+ "status"), "Submitted")
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
"Batched for Billing")
+ def test_sales_invoice_gl_entry_without_aii(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+ si = webnotes.bean(webnotes.copy_doclist(test_records[1]))
+ si.insert()
+ si.submit()
-test_dependencies = ["Journal Voucher"]
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ order by account asc""", si.doc.name, as_dict=1)
+ self.assertTrue(gl_entries)
+
+ expected_values = sorted([
+ [si.doc.debit_to, 630.0, 0.0],
+ [test_records[1][1]["income_account"], 0.0, 500.0],
+ [test_records[1][2]["account_head"], 0.0, 80.0],
+ [test_records[1][3]["account_head"], 0.0, 50.0],
+ ])
+
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_values[i][0], gle.account)
+ self.assertEquals(expected_values[i][1], gle.debit)
+ self.assertEquals(expected_values[i][2], gle.credit)
+
+ # cancel
+ si.cancel()
+
+ gle_count = webnotes.conn.sql("""select count(name) from `tabGL Entry`
+ where voucher_type='Sales Invoice' and voucher_no=%s
+ and ifnull(is_cancelled, 'No') = 'Yes'
+ order by account asc""", si.doc.name)
+
+ self.assertEquals(gle_count[0][0], 8)
+
+ def test_pos_gl_entry_with_aii(self):
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ self._insert_purchase_receipt()
+ self._insert_pos_settings()
+
+ pos = webnotes.copy_doclist(test_records[1])
+ pos[0]["is_pos"] = 1
+ pos[0]["update_stock"] = 1
+ pos[0]["posting_time"] = "12:05"
+ pos[0]["cash_bank_account"] = "_Test Account Bank Account - _TC"
+ pos[0]["paid_amount"] = 600.0
-test_records = [[
- {
- "naming_series": "_T-Sales Invoice-",
- "company": "_Test Company",
- "conversion_rate": 1.0,
- "currency": "INR",
- "debit_to": "_Test Customer - _TC",
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "doctype": "Sales Invoice",
- "due_date": "2013-01-23",
- "fiscal_year": "_Test Fiscal Year 2013",
- "grand_total": 561.8,
- "grand_total_export": 561.8,
- "net_total": 500.0,
- "plc_conversion_rate": 1.0,
- "posting_date": "2013-01-23",
- "price_list_currency": "INR",
- "price_list_name": "_Test Price List",
- "territory": "_Test Territory"
- },
- {
- "amount": 500.0,
- "basic_rate": 500.0,
- "description": "138-CMS Shoe",
- "doctype": "Sales Invoice Item",
- "export_amount": 500.0,
- "export_rate": 500.0,
- "income_account": "Sales - _TC",
- "cost_center": "_Test Cost Center - _TC",
- "item_name": "138-CMS Shoe",
- "parentfield": "entries",
- "qty": 1.0
- },
- {
- "account_head": "_Test Account VAT - _TC",
- "charge_type": "On Net Total",
- "description": "VAT",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "tax_amount": 30.0,
- },
- {
- "account_head": "_Test Account Service Tax - _TC",
- "charge_type": "On Net Total",
- "description": "Service Tax",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "tax_amount": 31.8,
- }
-]]
\ No newline at end of file
+ si = webnotes.bean(pos)
+ si.insert()
+ si.submit()
+
+ # check stock ledger entries
+ sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry`
+ where voucher_type = 'Sales Invoice' and voucher_no = %s""", si.doc.name, as_dict=1)[0]
+ self.assertTrue(sle)
+ self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty],
+ ["_Test Item", "_Test Warehouse", -5.0])
+
+ # check gl entries
+ stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
+ "stock_in_hand_account")
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ order by account asc, debit asc""", si.doc.name, as_dict=1)
+ self.assertTrue(gl_entries)
+
+ expected_gl_entries = sorted([
+ [si.doc.debit_to, 630.0, 0.0],
+ [test_records[1][1]["income_account"], 0.0, 500.0],
+ [test_records[1][2]["account_head"], 0.0, 80.0],
+ [test_records[1][3]["account_head"], 0.0, 50.0],
+ [stock_in_hand_account, 0.0, 375.0],
+ [test_records[1][1]["expense_account"], 375.0, 0.0],
+ [si.doc.debit_to, 0.0, 600.0],
+ ["_Test Account Bank Account - _TC", 600.0, 0.0]
+ ])
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_gl_entries[i][0], gle.account)
+ self.assertEquals(expected_gl_entries[i][1], gle.debit)
+ self.assertEquals(expected_gl_entries[i][2], gle.credit)
+
+ # cancel
+ si.cancel()
+ gl_count = webnotes.conn.sql("""select count(name)
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ and ifnull(is_cancelled, 'No') = 'Yes'
+ order by account asc, name asc""", si.doc.name)
+
+ self.assertEquals(gl_count[0][0], 16)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+ def test_sales_invoice_gl_entry_with_aii_no_item_code(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ si_copy = webnotes.copy_doclist(test_records[1])
+ si_copy[1]["item_code"] = None
+ si = webnotes.bean(si_copy)
+ si.insert()
+ si.submit()
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ order by account asc""", si.doc.name, as_dict=1)
+ self.assertTrue(gl_entries)
+
+ expected_values = sorted([
+ [si.doc.debit_to, 630.0, 0.0],
+ [test_records[1][1]["income_account"], 0.0, 500.0],
+ [test_records[1][2]["account_head"], 0.0, 80.0],
+ [test_records[1][3]["account_head"], 0.0, 50.0],
+ ])
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_values[i][0], gle.account)
+ self.assertEquals(expected_values[i][1], gle.debit)
+ self.assertEquals(expected_values[i][2], gle.credit)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+ def test_sales_invoice_gl_entry_with_aii_non_stock_item(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ si_copy = webnotes.copy_doclist(test_records[1])
+ si_copy[1]["item_code"] = "_Test Non Stock Item"
+ si = webnotes.bean(si_copy)
+ si.insert()
+ si.submit()
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ order by account asc""", si.doc.name, as_dict=1)
+ self.assertTrue(gl_entries)
+
+ expected_values = sorted([
+ [si.doc.debit_to, 630.0, 0.0],
+ [test_records[1][1]["income_account"], 0.0, 500.0],
+ [test_records[1][2]["account_head"], 0.0, 80.0],
+ [test_records[1][3]["account_head"], 0.0, 50.0],
+ ])
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_values[i][0], gle.account)
+ self.assertEquals(expected_values[i][1], gle.debit)
+ self.assertEquals(expected_values[i][2], gle.credit)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+ def _insert_purchase_receipt(self):
+ from stock.doctype.purchase_receipt.test_purchase_receipt import test_records \
+ as pr_test_records
+ pr = webnotes.bean(copy=pr_test_records[0])
+ pr.run_method("calculate_taxes_and_totals")
+ pr.insert()
+ pr.submit()
+
+ def _insert_delivery_note(self):
+ from stock.doctype.delivery_note.test_delivery_note import test_records \
+ as dn_test_records
+ dn = webnotes.bean(copy=dn_test_records[0])
+ dn.insert()
+ dn.submit()
+ return dn
+
+ def _insert_pos_settings(self):
+ webnotes.conn.sql("""delete from `tabPOS Setting`""")
+ ps = webnotes.bean([
+ {
+ "cash_bank_account": "_Test Account Bank Account - _TC",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "cost_center": "_Test Cost Center - _TC",
+ "currency": "INR",
+ "doctype": "POS Setting",
+ "income_account": "_Test Account Bank Account - _TC",
+ "price_list_name": "_Test Price List",
+ "territory": "_Test Territory",
+ "warehouse": "_Test Warehouse"
+ }
+ ])
+ ps.insert()
+
+ def test_sales_invoice_with_advance(self):
+ from accounts.doctype.journal_voucher.test_journal_voucher \
+ import test_records as jv_test_records
+
+ jv = webnotes.bean(copy=jv_test_records[0])
+ jv.insert()
+ jv.submit()
+
+ si = webnotes.bean(copy=test_records[0])
+ si.doclist.append({
+ "doctype": "Sales Invoice Advance",
+ "parentfield": "advance_adjustment_details",
+ "journal_voucher": jv.doc.name,
+ "jv_detail_no": jv.doclist[1].name,
+ "advance_amount": 400,
+ "allocated_amount": 300,
+ "remarks": jv.doc.remark
+ })
+ si.insert()
+ si.submit()
+ si.load_from_db()
+
+ self.assertTrue(webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_invoice=%s""", si.doc.name))
+
+ self.assertTrue(webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_invoice=%s and credit=300""", si.doc.name))
+
+ self.assertEqual(si.doc.outstanding_amount, 261.8)
+
+ si.cancel()
+
+ self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
+ where against_invoice=%s""", si.doc.name))
+
+ def test_recurring_invoice(self):
+ from webnotes.utils import now_datetime, get_first_day, get_last_day, add_to_date
+ today = now_datetime().date()
+
+ base_si = webnotes.bean(copy=test_records[0])
+ base_si.doc.fields.update({
+ "convert_into_recurring_invoice": 1,
+ "recurring_type": "Monthly",
+ "notification_email_address": "test@example.com, test1@example.com, test2@example.com",
+ "repeat_on_day_of_month": today.day,
+ "posting_date": today,
+ "invoice_period_from_date": get_first_day(today),
+ "invoice_period_to_date": get_last_day(today)
+ })
+
+ # monthly
+ si1 = webnotes.bean(copy=base_si.doclist)
+ si1.insert()
+ si1.submit()
+ self._test_recurring_invoice(si1, True)
+
+ # monthly without a first and last day period
+ si2 = webnotes.bean(copy=base_si.doclist)
+ si2.doc.fields.update({
+ "invoice_period_from_date": today,
+ "invoice_period_to_date": add_to_date(today, days=30)
+ })
+ si2.insert()
+ si2.submit()
+ self._test_recurring_invoice(si2, False)
+
+ # quarterly
+ si3 = webnotes.bean(copy=base_si.doclist)
+ si3.doc.fields.update({
+ "recurring_type": "Quarterly",
+ "invoice_period_from_date": get_first_day(today),
+ "invoice_period_to_date": get_last_day(add_to_date(today, months=3))
+ })
+ si3.insert()
+ si3.submit()
+ self._test_recurring_invoice(si3, True)
+
+ # quarterly without a first and last day period
+ si4 = webnotes.bean(copy=base_si.doclist)
+ si4.doc.fields.update({
+ "recurring_type": "Quarterly",
+ "invoice_period_from_date": today,
+ "invoice_period_to_date": add_to_date(today, months=3)
+ })
+ si4.insert()
+ si4.submit()
+ self._test_recurring_invoice(si4, False)
+
+ # yearly
+ si5 = webnotes.bean(copy=base_si.doclist)
+ si5.doc.fields.update({
+ "recurring_type": "Yearly",
+ "invoice_period_from_date": get_first_day(today),
+ "invoice_period_to_date": get_last_day(add_to_date(today, years=1))
+ })
+ si5.insert()
+ si5.submit()
+ self._test_recurring_invoice(si5, True)
+
+ # yearly without a first and last day period
+ si6 = webnotes.bean(copy=base_si.doclist)
+ si6.doc.fields.update({
+ "recurring_type": "Yearly",
+ "invoice_period_from_date": today,
+ "invoice_period_to_date": add_to_date(today, years=1)
+ })
+ si6.insert()
+ si6.submit()
+ self._test_recurring_invoice(si6, False)
+
+ # change posting date but keep recuring day to be today
+ si7 = webnotes.bean(copy=base_si.doclist)
+ si7.doc.fields.update({
+ "posting_date": add_to_date(today, days=-3)
+ })
+ si7.insert()
+ si7.submit()
+
+ # setting so that _test function works
+ si7.doc.posting_date = today
+ self._test_recurring_invoice(si7, True)
+
+ def _test_recurring_invoice(self, base_si, first_and_last_day):
+ from webnotes.utils import add_months, get_last_day, getdate
+ from accounts.doctype.sales_invoice.sales_invoice import manage_recurring_invoices
+
+ no_of_months = ({"Monthly": 1, "Quarterly": 3, "Yearly": 12})[base_si.doc.recurring_type]
+
+ def _test(i):
+ self.assertEquals(i+1, webnotes.conn.sql("""select count(*) from `tabSales Invoice`
+ where recurring_id=%s and docstatus=1""", base_si.doc.recurring_id)[0][0])
+
+ next_date = add_months(base_si.doc.posting_date, no_of_months)
+
+ manage_recurring_invoices(next_date=next_date, commit=False)
+
+ recurred_invoices = webnotes.conn.sql("""select name from `tabSales Invoice`
+ where recurring_id=%s and docstatus=1 order by name desc""", base_si.doc.recurring_id)
+
+ self.assertEquals(i+2, len(recurred_invoices))
+
+ new_si = webnotes.bean("Sales Invoice", recurred_invoices[0][0])
+
+ for fieldname in ["convert_into_recurring_invoice", "recurring_type",
+ "repeat_on_day_of_month", "notification_email_address"]:
+ self.assertEquals(base_si.doc.fields.get(fieldname),
+ new_si.doc.fields.get(fieldname))
+
+ self.assertEquals(new_si.doc.posting_date, unicode(next_date))
+
+ self.assertEquals(new_si.doc.invoice_period_from_date,
+ unicode(add_months(base_si.doc.invoice_period_from_date, no_of_months)))
+
+ if first_and_last_day:
+ self.assertEquals(new_si.doc.invoice_period_to_date,
+ unicode(get_last_day(add_months(base_si.doc.invoice_period_to_date,
+ no_of_months))))
+ else:
+ self.assertEquals(new_si.doc.invoice_period_to_date,
+ unicode(add_months(base_si.doc.invoice_period_to_date, no_of_months)))
+
+ self.assertEquals(getdate(new_si.doc.posting_date).day,
+ base_si.doc.repeat_on_day_of_month)
+
+ return new_si
+
+ # if yearly, test 3 repetitions, else test 13 repetitions
+ count = no_of_months == 12 and 3 or 13
+ for i in xrange(count):
+ base_si = _test(i)
+
+test_dependencies = ["Journal Voucher", "POS Setting"]
+
+test_records = [
+ [
+ {
+ "naming_series": "_T-Sales Invoice-",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "debit_to": "_Test Customer - _TC",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-01-23",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total": 561.8,
+ "grand_total_export": 561.8,
+ "net_total": 500.0,
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-01-23",
+ "price_list_currency": "INR",
+ "price_list_name": "_Test Price List",
+ "territory": "_Test Territory"
+ },
+ {
+ "amount": 500.0,
+ "basic_rate": 500.0,
+ "description": "138-CMS Shoe",
+ "doctype": "Sales Invoice Item",
+ "export_amount": 500.0,
+ "export_rate": 500.0,
+ "income_account": "Sales - _TC",
+ "cost_center": "_Test Cost Center - _TC",
+ "item_name": "138-CMS Shoe",
+ "parentfield": "entries",
+ "qty": 1.0
+ },
+ {
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 30.0,
+ },
+ {
+ "account_head": "_Test Account Service Tax - _TC",
+ "charge_type": "On Net Total",
+ "description": "Service Tax",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 31.8,
+ },
+ {
+ "parentfield": "sales_team",
+ "doctype": "Sales Team",
+ "sales_person": "_Test Sales Person 1",
+ "allocated_percentage": 65.5,
+ },
+ {
+ "parentfield": "sales_team",
+ "doctype": "Sales Team",
+ "sales_person": "_Test Sales Person 2",
+ "allocated_percentage": 34.5,
+ },
+ ],
+ [
+ {
+ "naming_series": "_T-Sales Invoice-",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "debit_to": "_Test Customer - _TC",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-01-23",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total": 630.0,
+ "grand_total_export": 630.0,
+ "net_total": 500.0,
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-03-07",
+ "price_list_currency": "INR",
+ "price_list_name": "_Test Price List",
+ "territory": "_Test Territory"
+ },
+ {
+ "item_code": "_Test Item",
+ "item_name": "_Test Item",
+ "description": "_Test Item",
+ "doctype": "Sales Invoice Item",
+ "parentfield": "entries",
+ "qty": 5.0,
+ "basic_rate": 500.0,
+ "amount": 500.0,
+ "export_rate": 500.0,
+ "export_amount": 500.0,
+ "income_account": "Sales - _TC",
+ "expense_account": "_Test Account Cost for Goods Sold - _TC",
+ "cost_center": "_Test Cost Center - _TC",
+ },
+ {
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 80.0,
+ },
+ {
+ "account_head": "_Test Account Service Tax - _TC",
+ "charge_type": "On Net Total",
+ "description": "Service Tax",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 50.0,
+ }
+ ],
+]
\ No newline at end of file
diff --git a/accounts/doctype/sales_invoice_advance/sales_invoice_advance.txt b/accounts/doctype/sales_invoice_advance/sales_invoice_advance.txt
index 6216c89..32ef4c5 100644
--- a/accounts/doctype/sales_invoice_advance/sales_invoice_advance.txt
+++ b/accounts/doctype/sales_invoice_advance/sales_invoice_advance.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:09",
+ "creation": "2013-02-22 01:27:41",
"docstatus": 0,
- "modified": "2013-01-29 16:27:51",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -33,6 +33,7 @@
"oldfieldname": "journal_voucher",
"oldfieldtype": "Link",
"options": "Journal Voucher",
+ "print_width": "250px",
"read_only": 1,
"width": "250px"
},
@@ -45,6 +46,7 @@
"oldfieldname": "jv_detail_no",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
},
@@ -56,6 +58,7 @@
"oldfieldname": "advance_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
},
@@ -67,6 +70,7 @@
"oldfieldname": "allocated_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
+ "print_width": "120px",
"width": "120px"
},
{
@@ -76,6 +80,7 @@
"label": "Remarks",
"oldfieldname": "remarks",
"oldfieldtype": "Small Text",
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
}
diff --git a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
index ae1afe9..bc51198 100644
--- a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
+++ b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-29 19:25:49",
+ "creation": "2013-03-07 11:42:55",
"docstatus": 0,
- "modified": "2013-03-01 13:41:51",
+ "modified": "2013-03-21 18:35:47",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -30,7 +30,8 @@
"fieldname": "barcode",
"fieldtype": "Data",
"label": "Barcode",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -42,6 +43,7 @@
"oldfieldtype": "Link",
"options": "Item",
"print_hide": 0,
+ "read_only": 0,
"reqd": 0,
"search_index": 1
},
@@ -63,6 +65,7 @@
"oldfieldname": "item_name",
"oldfieldtype": "Data",
"print_hide": 1,
+ "read_only": 0,
"reqd": 1,
"search_index": 0
},
@@ -73,6 +76,8 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "200px",
+ "read_only": 0,
"reqd": 1,
"width": "200px"
},
@@ -83,6 +88,7 @@
"label": "Qty",
"oldfieldname": "qty",
"oldfieldtype": "Currency",
+ "read_only": 0,
"reqd": 0
},
{
@@ -101,6 +107,7 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 1,
+ "read_only": 0,
"reqd": 0
},
{
@@ -110,7 +117,8 @@
"label": "Discount (%)",
"oldfieldname": "adj_rate",
"oldfieldtype": "Float",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -120,6 +128,7 @@
"oldfieldname": "export_rate",
"oldfieldtype": "Currency",
"options": "currency",
+ "read_only": 0,
"reqd": 1
},
{
@@ -154,6 +163,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "read_only": 0,
"reqd": 1,
"search_index": 0
},
@@ -178,7 +188,8 @@
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -190,11 +201,24 @@
"oldfieldtype": "Link",
"options": "Account",
"print_hide": 1,
+ "print_width": "120px",
+ "read_only": 0,
"reqd": 1,
"width": "120px"
},
{
"doctype": "DocField",
+ "fieldname": "expense_account",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "in_filter": 1,
+ "label": "Expense Account",
+ "options": "Account",
+ "print_hide": 1,
+ "width": "120px"
+ },
+ {
+ "doctype": "DocField",
"fieldname": "cost_center",
"fieldtype": "Link",
"in_filter": 1,
@@ -203,6 +227,8 @@
"oldfieldtype": "Link",
"options": "Cost Center",
"print_hide": 1,
+ "print_width": "120px",
+ "read_only": 0,
"reqd": 0,
"width": "120px"
},
@@ -214,7 +240,8 @@
"label": "Serial No",
"oldfieldname": "serial_no",
"oldfieldtype": "Small Text",
- "print_hide": 0
+ "print_hide": 0,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -222,7 +249,8 @@
"fieldtype": "Link",
"label": "Batch No",
"options": "Batch",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -246,7 +274,8 @@
"label": "Brand Name",
"oldfieldname": "brand",
"oldfieldtype": "Data",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -325,7 +354,8 @@
"fieldname": "time_log_batch",
"fieldtype": "Link",
"label": "Time Log Batch",
- "options": "Time Log Batch"
+ "options": "Time Log Batch",
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -351,6 +381,17 @@
"read_only": 1
},
{
+ "doctype": "DocField",
+ "fieldname": "buying_amount",
+ "fieldtype": "Currency",
+ "hidden": 1,
+ "label": "Buying Amount",
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "print_hide": 1,
+ "read_only": 1
+ },
+ {
"allow_on_submit": 1,
"doctype": "DocField",
"fieldname": "page_break",
@@ -358,6 +399,7 @@
"label": "Page Break",
"no_copy": 1,
"print_hide": 1,
+ "read_only": 0,
"report_hide": 1
}
]
\ No newline at end of file
diff --git a/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt b/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
index bbac704..3b32524 100644
--- a/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
+++ b/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-24 15:56:19",
+ "creation": "2013-02-22 01:27:41",
"docstatus": 0,
- "modified": "2013-01-29 16:28:04",
+ "modified": "2013-03-07 07:03:31",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -63,6 +63,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Small Text",
+ "print_width": "300px",
"reqd": 1,
"width": "300px"
},
@@ -163,6 +164,7 @@
"label": "Is this Tax included in Basic Rate?",
"no_copy": 0,
"print_hide": 1,
+ "print_width": "150px",
"report_hide": 1,
"width": "150px"
}
diff --git a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
index 7d441ab..b1cbbdc 100644
--- a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
+++ b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
@@ -45,8 +45,7 @@
var make_row = function(title,val,bold){
var bstart = '<b>'; var bend = '</b>';
return '<tr><td style="width:50%;">'+(bold?bstart:'')+title+(bold?bend:'')+'</td>'
- +'<td style="width:25%;text-align:right;"></td>'
- +'<td style="width:25%;text-align:right;">'+format_currency(val, doc.currency)+'</td>'
+ +'<td style="width:50%;text-align:right;">'+format_currency(val, doc.currency)+'</td>'
+'</tr>'
}
diff --git a/accounts/general_ledger.py b/accounts/general_ledger.py
index 215c351..8e0f408 100644
--- a/accounts/general_ledger.py
+++ b/accounts/general_ledger.py
@@ -16,7 +16,7 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import flt, cstr
+from webnotes.utils import flt, cstr, now
from webnotes.model.doc import Document
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
@@ -109,5 +109,7 @@
(total_debit - total_credit), raise_exception=1)
def set_as_cancel(voucher_type, voucher_no):
- webnotes.conn.sql("""update `tabGL Entry` set is_cancelled='Yes'
- where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
\ No newline at end of file
+ webnotes.conn.sql("""update `tabGL Entry` set is_cancelled='Yes',
+ modified=%s, modified_by=%s
+ where voucher_type=%s and voucher_no=%s""",
+ (now(), webnotes.session.user, voucher_type, voucher_no))
\ No newline at end of file
diff --git a/accounts/page/accounts_browser/accounts_browser.js b/accounts/page/accounts_browser/accounts_browser.js
index 6fd0c66..97c8554 100644
--- a/accounts/page/accounts_browser/accounts_browser.js
+++ b/accounts/page/accounts_browser/accounts_browser.js
@@ -109,11 +109,11 @@
},
onrender: function(treenode) {
- if (ctype == 'Account') {
- var bal = treenode.data && treenode.data.balance.split(' ') || ['',''];
- if (bal && flt(bal[1])) {
+ if (ctype == 'Account' && treenode.data) {
+ if(treenode.data.balance) {
treenode.parent.append('<span class="balance-area">'
- + format_currency(bal[1], bal[0]) + '</span>');
+ + format_currency(treenode.data.balance, treenode.data.currency)
+ + '</span>');
}
}
}
diff --git a/accounts/page/accounts_browser/accounts_browser.py b/accounts/page/accounts_browser/accounts_browser.py
index 68f8357..d78b8a2 100644
--- a/accounts/page/accounts_browser/accounts_browser.py
+++ b/accounts/page/accounts_browser/accounts_browser.py
@@ -1,7 +1,7 @@
from __future__ import unicode_literals
import webnotes
import webnotes.defaults
-
+from webnotes.utils import flt
from accounts.utils import get_balance_on
@webnotes.whitelist()
@@ -53,6 +53,7 @@
currency = webnotes.conn.sql("select default_currency from `tabCompany` where name = %s", company)[0][0]
for each in acc:
bal = get_balance_on(each.get("value"))
- each['balance'] = currency + ' ' + str(bal or 0)
+ each["currency"] = currency
+ each["balance"] = flt(bal)
return acc
diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js
index f2faf93..403d7bd 100644
--- a/accounts/page/accounts_home/accounts_home.js
+++ b/accounts/page/accounts_home/accounts_home.js
@@ -64,12 +64,6 @@
description: "Close Balance Sheet and book Profit or Loss."
},
{
- "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool",
- "label": wn._("Sales and Purchase Return Tool"),
- description: wn._("Manage sales or purchase returns"),
- "doctype": "Sales and Purchase Return Tool"
- },
- {
"page":"voucher-import-tool",
"label": wn._("Voucher Import Tool"),
"description": "Import accounting entries from CSV."
diff --git a/accounts/page/financial_analytics/financial_analytics.js b/accounts/page/financial_analytics/financial_analytics.js
index f0bafdb..f714549 100644
--- a/accounts/page/financial_analytics/financial_analytics.js
+++ b/accounts/page/financial_analytics/financial_analytics.js
@@ -71,9 +71,11 @@
setup_filters: function() {
var me = this;
this._super();
- this.filter_inputs.pl_or_bs.change(function() {
- me.filter_inputs.refresh.click();
- }).add_options($.map(wn.report_dump.data["Cost Center"], function(v) {return v.name;}));
+ this.trigger_refresh_on_change(["pl_or_bs"]);
+
+ this.filter_inputs.pl_or_bs
+ .add_options($.map(wn.report_dump.data["Cost Center"], function(v) {return v.name;}));
+
this.setup_plot_check();
},
init_filter_values: function() {
diff --git a/accounts/page/general_ledger/general_ledger.js b/accounts/page/general_ledger/general_ledger.js
index 8f6b598..4a3f21e 100644
--- a/accounts/page/general_ledger/general_ledger.js
+++ b/accounts/page/general_ledger/general_ledger.js
@@ -108,7 +108,7 @@
// filter accounts options by company
this.filter_inputs.company.change(function() {
me.setup_account_filter(this);
- me.filter_inputs.refresh.click();
+ me.set_route()
});
this.filter_inputs.account.change(function() {
diff --git a/accounts/report/gross_profit/gross_profit.js b/accounts/report/gross_profit/gross_profit.js
index 77ac581..aa6be55 100644
--- a/accounts/report/gross_profit/gross_profit.js
+++ b/accounts/report/gross_profit/gross_profit.js
@@ -6,6 +6,18 @@
"fieldtype": "Link",
"options": "Company",
"default": wn.defaults.get_user_default("company")
- }
+ },
+ {
+ "fieldname":"from_date",
+ "label": "From Date",
+ "fieldtype": "Date",
+ "default": wn.defaults.get_user_default("year_start_date")
+ },
+ {
+ "fieldname":"to_date",
+ "label": "To Date",
+ "fieldtype": "Date",
+ "default": wn.defaults.get_user_default("year_end_date")
+ },
]
}
\ No newline at end of file
diff --git a/accounts/report/gross_profit/gross_profit.py b/accounts/report/gross_profit/gross_profit.py
index de8651b..5c06637 100644
--- a/accounts/report/gross_profit/gross_profit.py
+++ b/accounts/report/gross_profit/gross_profit.py
@@ -1,87 +1,99 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import flt
-
-stock_ledger_entries = None
-item_sales_bom = None
+from stock.utils import get_buying_amount
def execute(filters=None):
if not filters: filters = {}
- get_stock_ledger_entries(filters)
- get_sales_bom()
+ stock_ledger_entries = get_stock_ledger_entries(filters)
- delivery_note_items = webnotes.conn.sql("""select dn.name, dn.posting_date, dn.posting_time,
- dn.project_name, item.item_code, item.item_name, item.description, item.warehouse,
- item.qty, item.basic_rate, item.amount, item.name as "item_row"
- from `tabDelivery Note` dn, `tabDelivery Note Item` item
- where item.parent = dn.name and dn.docstatus = 1
- order by dn.posting_date desc, dn.posting_time desc""", as_dict=1)
+ source = get_source_data(filters)
- columns = ["Delivery Note:Link/Delivery Note", "Posting Date:Date", "Posting Time",
+ item_sales_bom = get_item_sales_bom()
+
+ columns = ["Delivery Note/Sales Invoice::120", "Posting Date:Date", "Posting Time",
"Item Code:Link/Item", "Item Name", "Description", "Warehouse:Link/Warehouse",
"Qty:Float", "Selling Rate:Currency", "Selling Amount:Currency", "Buying Amount:Currency",
"Gross Profit:Currency", "Gross Profit %:Percent", "Project:Link/Project"]
-
+
data = []
- for row in delivery_note_items:
+ for row in source:
selling_amount = flt(row.amount)
- buying_amount = get_buying_amount(row)
+ buying_amount = get_buying_amount(row.item_code, row.warehouse, -1*row.qty,
+ row.parenttype, row.name, row.item_row, stock_ledger_entries,
+ item_sales_bom.get(row.parenttype, {}).get(row.name, webnotes._dict()))
+
+ buying_amount = buying_amount > 0 and buying_amount or 0
+
if selling_amount:
gross_profit = selling_amount - buying_amount
gross_profit_percent = (gross_profit / selling_amount) * 100.0
else:
gross_profit = gross_profit_percent = 0.0
- data.append([row.name, row.posting_date, row.posting_time, row.item_code, row.item_name,
+ name = """<a href="%s">%s</a>""" % ("/".join(["#Form", row.parenttype, row.name]), row.name)
+ data.append([name, row.posting_date, row.posting_time, row.item_code, row.item_name,
row.description, row.warehouse, row.qty, row.basic_rate, row.amount, buying_amount,
gross_profit, gross_profit_percent, row.project])
return columns, data
-
-def get_buying_amount(row):
- if item_sales_bom.get(row.item_code):
- # sales bom item
- buying_amount = 0.0
- for bom_item in item_sales_bom[row.item_code]:
- buying_amount += _get_buying_amount(row.name, "[** No Item Row **]",
- bom_item.item_code, row.warehouse, bom_item.qty * row.qty)
- return buying_amount
- else:
- # doesn't have sales bom
- return _get_buying_amount(row.name, row.item_row, row.item_code, row.warehouse, row.qty)
-
-def _get_buying_amount(voucher_no, item_row, item_code, warehouse, qty):
- for i, sle in enumerate(stock_ledger_entries):
- if sle.voucher_type == "Delivery Note" and sle.voucher_no == voucher_no:
- if (sle.voucher_detail_no == item_row) or \
- (sle.item_code == item_code and sle.warehouse == warehouse and \
- abs(flt(sle.qty)) == qty):
- buying_amount = flt(stock_ledger_entries[i+1].stock_value) - flt(sle.stock_value)
-
- return buying_amount
-
- return 0.0
-
-def get_sales_bom():
- global item_sales_bom
- item_sales_bom = {}
-
- for r in webnotes.conn.sql("""select parent, item_code, qty from `tabSales BOM Item`""", as_dict=1):
- item_sales_bom.setdefault(r.parent, []).append(r)
-
-def get_stock_ledger_entries(filters):
- global stock_ledger_entries
-
+def get_stock_ledger_entries(filters):
query = """select item_code, voucher_type, voucher_no,
voucher_detail_no, posting_date, posting_time, stock_value,
warehouse, actual_qty as qty
- from `tabStock Ledger Entry` where ifnull(`is_cancelled`, "No") = "No" """
+ from `tabStock Ledger Entry`
+ where ifnull(`is_cancelled`, "No") = "No" """
if filters.get("company"):
query += """ and company=%(company)s"""
query += " order by item_code desc, warehouse desc, posting_date desc, posting_time desc, name desc"
- stock_ledger_entries = webnotes.conn.sql(query, filters, as_dict=True)
+ return webnotes.conn.sql(query, filters, as_dict=True)
+
+def get_item_sales_bom():
+ item_sales_bom = {}
+
+ for d in webnotes.conn.sql("""select parenttype, parent, parent_item,
+ item_code, warehouse, -1*qty as total_qty
+ from `tabDelivery Note Packing Item` where docstatus=1""", as_dict=True):
+ item_sales_bom.setdefault(d.parenttype, webnotes._dict()).setdefault(d.parent,
+ webnotes._dict()).setdefault(d.parent_item, []).append(d)
+
+ return item_sales_bom
+
+def get_source_data(filters):
+ conditions = ""
+ if filters.get("company"):
+ conditions += " and company=%(company)s"
+ if filters.get("from_date"):
+ conditions += " and posting_date>=%(from_date)s"
+ if filters.get("to_date"):
+ conditions += " and posting_date<=%(to_date)s"
+
+ delivery_note_items = webnotes.conn.sql("""select item.parenttype, dn.name,
+ dn.posting_date, dn.posting_time, dn.project_name,
+ item.item_code, item.item_name, item.description, item.warehouse,
+ item.qty, item.basic_rate, item.amount, item.name as "item_row",
+ timestamp(dn.posting_date, dn.posting_time) as posting_datetime
+ from `tabDelivery Note` dn, `tabDelivery Note Item` item
+ where item.parent = dn.name and dn.docstatus = 1 %s
+ order by dn.posting_date desc, dn.posting_time desc""" % (conditions,), filters, as_dict=1)
+
+ sales_invoice_items = webnotes.conn.sql("""select item.parenttype, si.name,
+ si.posting_date, si.posting_time, si.project_name,
+ item.item_code, item.item_name, item.description, item.warehouse,
+ item.qty, item.basic_rate, item.amount, item.name as "item_row",
+ timestamp(si.posting_date, si.posting_time) as posting_datetime
+ from `tabSales Invoice` si, `tabSales Invoice Item` item
+ where item.parent = si.name and si.docstatus = 1 %s
+ and si.is_pos = 1 and si.update_stock = 1
+ order by si.posting_date desc, si.posting_time desc""" % (conditions,), filters, as_dict=1)
+
+ source = delivery_note_items + sales_invoice_items
+ if len(source) > len(delivery_note_items):
+ source.sort(key=lambda d: d.posting_datetime, reverse=True)
+
+ return source
\ No newline at end of file
diff --git a/accounts/search_criteria/trend_analyzer/trend_analyzer.js b/accounts/search_criteria/trend_analyzer/trend_analyzer.js
index 7f4b94b..59d9483 100644
--- a/accounts/search_criteria/trend_analyzer/trend_analyzer.js
+++ b/accounts/search_criteria/trend_analyzer/trend_analyzer.js
@@ -16,6 +16,7 @@
report.customize_filters = function() {
this.hide_all_filters();
+ this.dt.set_no_limit(1);
// hide transaction based on permissions
var all_transactions = ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice",
diff --git a/accounts/utils.py b/accounts/utils.py
index 14ceb4e..051cdd1 100644
--- a/accounts/utils.py
+++ b/accounts/utils.py
@@ -17,7 +17,7 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import nowdate, cstr, flt
+from webnotes.utils import nowdate, cstr, flt, now
from webnotes.model.doc import addchild
from webnotes import msgprint, _
from webnotes.utils import formatdate
@@ -233,4 +233,18 @@
return webnotes.conn.sql("""select name, parent_cost_center from `tabCost Center`
where docstatus < 2 %s and %s like %s order by name limit %s, %s""" %
(conditions, searchfield, "%s", "%s", "%s"),
- tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
\ No newline at end of file
+ tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
+
+def remove_against_link_from_jv(ref_type, ref_no, against_field):
+ webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null,
+ modified=%s, modified_by=%s
+ where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
+ (now(), webnotes.session.user, ref_no))
+
+ webnotes.conn.sql("""update `tabGL Entry`
+ set against_voucher_type=null, against_voucher=null,
+ modified=%s, modified_by=%s
+ where against_voucher_type=%s and against_voucher=%s
+ and voucher_no != ifnull(against_voucher, "")
+ and ifnull(is_cancelled, "No")="No" """,
+ (now(), webnotes.session.user, ref_type, ref_no))
diff --git a/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js
index 05b7bcb..dacee80 100644
--- a/buying/doctype/purchase_common/purchase_common.js
+++ b/buying/doctype/purchase_common/purchase_common.js
@@ -21,7 +21,7 @@
wn.provide("erpnext.buying");
-erpnext.buying.BuyingController = erpnext.utils.Controller.extend({
+erpnext.buying.BuyingController = wn.ui.form.Controller.extend({
setup: function() {
var me = this;
@@ -68,15 +68,15 @@
callback: function(r) {
if(!r.exc) {
me.price_list_currency();
- if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype,
- me.frm.doc.name);
+ if (typeof callback_fn === "function")
+ callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
}
}
});
} else {
me.price_list_currency();
- if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype,
- me.frm.doc.name);
+ if (typeof callback_fn === "function")
+ callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
}
}
},
diff --git a/buying/doctype/purchase_order/purchase_order.py b/buying/doctype/purchase_order/purchase_order.py
index 438442c..218d4bf 100644
--- a/buying/doctype/purchase_order/purchase_order.py
+++ b/buying/doctype/purchase_order/purchase_order.py
@@ -132,6 +132,10 @@
for d in getlist(self.doclist, 'po_details'):
#1. Check if is_stock_item == 'Yes'
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
+ # this happens when item is changed from non-stock to stock item
+ if not d.warehouse:
+ continue
+
ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor)
if is_stopped:
po_qty = flt(d.qty) > flt(d.received_qty) and \
diff --git a/buying/doctype/purchase_order_item/purchase_order_item.txt b/buying/doctype/purchase_order_item/purchase_order_item.txt
index edb3092..cd00f87 100755
--- a/buying/doctype/purchase_order_item/purchase_order_item.txt
+++ b/buying/doctype/purchase_order_item/purchase_order_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-07 11:00:11",
+ "creation": "2013-02-22 01:27:42",
"docstatus": 0,
- "modified": "2013-02-18 13:39:02",
+ "modified": "2013-03-07 07:03:27",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.txt b/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.txt
index dd71989..d08963b 100644
--- a/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.txt
+++ b/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:10",
+ "creation": "2013-02-22 01:27:42",
"docstatus": 0,
- "modified": "2013-01-29 16:27:51",
+ "modified": "2013-03-07 07:03:28",
"modified_by": "Administrator",
"owner": "dhanalekshmi@webnotestech.com"
},
diff --git a/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.txt b/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.txt
index 4c5ba81..4c0ce0d 100644
--- a/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.txt
+++ b/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:10",
+ "creation": "2013-02-22 01:27:42",
"docstatus": 0,
- "modified": "2013-01-29 16:27:51",
+ "modified": "2013-03-07 07:03:28",
"modified_by": "Administrator",
"owner": "wasim@webnotestech.com"
},
@@ -70,6 +70,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Data",
+ "print_width": "300px",
"read_only": 1,
"width": "300px"
},
diff --git a/buying/doctype/quality_inspection_reading/quality_inspection_reading.txt b/buying/doctype/quality_inspection_reading/quality_inspection_reading.txt
index c9f6b2d..066185e 100644
--- a/buying/doctype/quality_inspection_reading/quality_inspection_reading.txt
+++ b/buying/doctype/quality_inspection_reading/quality_inspection_reading.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:35:52",
+ "creation": "2013-02-22 01:27:43",
"docstatus": 0,
- "modified": "2012-03-27 14:35:52",
+ "modified": "2013-03-07 07:03:29",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -11,10 +11,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Buying",
- "name": "__common__",
- "section_style": "Tray",
- "show_in_menu": 0,
- "version": 2
+ "name": "__common__"
},
{
"doctype": "DocField",
diff --git a/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt b/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
index cf79f04..53fa9f8 100644
--- a/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
+++ b/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-29 19:25:55",
+ "creation": "2013-02-22 01:27:43",
"docstatus": 0,
- "modified": "2013-02-18 13:39:45",
+ "modified": "2013-03-07 07:03:32",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/buying/page/buying_home/buying_home.js b/buying/page/buying_home/buying_home.js
index 922e7ac..2df5f6f 100644
--- a/buying/page/buying_home/buying_home.js
+++ b/buying/page/buying_home/buying_home.js
@@ -80,12 +80,6 @@
title: wn._("Tools"),
icon: "icon-wrench",
items: [
- {
- "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool",
- "label":wn._("Purchase Returns"),
- "description":wn._("Helper for managing return of goods (sales or purchase)"),
- doctype: "Sales and Purchase Return Tool"
- },
]
},
{
diff --git a/buying/page/purchase_analytics/purchase_analytics.js b/buying/page/purchase_analytics/purchase_analytics.js
index 7d8171e..fc082ea 100644
--- a/buying/page/purchase_analytics/purchase_analytics.js
+++ b/buying/page/purchase_analytics/purchase_analytics.js
@@ -120,19 +120,9 @@
setup_filters: function() {
var me = this;
this._super();
-
- this.filter_inputs.value_or_qty.change(function() {
- me.filter_inputs.refresh.click();
- });
-
- this.filter_inputs.tree_type.change(function() {
- me.filter_inputs.refresh.click();
- });
- this.filter_inputs.based_on.change(function() {
- me.filter_inputs.refresh.click();
- });
-
+ this.trigger_refresh_on_change(["value_or_qty", "tree_type", "based_on"]);
+
this.show_zero_check()
this.setup_plot_check();
},
diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py
index aa52b5e..ac6481c 100644
--- a/controllers/accounts_controller.py
+++ b/controllers/accounts_controller.py
@@ -18,11 +18,19 @@
import webnotes
from webnotes import msgprint, _
from webnotes.utils import flt
+
from utilities.transaction_base import TransactionBase
class AccountsController(TransactionBase):
- def get_gl_dict(self, args, cancel):
+ def validate(self):
+ if self.meta.get_field("grand_total"):
+ self.validate_value("grand_total", ">=", 0)
+
+ def get_gl_dict(self, args, cancel=None):
"""this method populates the common properties of a gl entry record"""
+ if cancel is None:
+ cancel = (self.doc.docstatus == 2)
+
gl_dict = {
'company': self.doc.company,
'posting_date': self.doc.posting_date,
@@ -67,16 +75,15 @@
"advance_amount": flt(d.amount),
"allocate_amount": 0
})
-
- def get_stock_in_hand_account(self):
- stock_in_hand_account = webnotes.conn.get_value("Company", self.doc.company, "stock_in_hand_account")
- if not stock_in_hand_account:
- msgprint(_("Missing") + ": "
- + _(webnotes.get_doctype("company").get_label("stock_in_hand_account")
- + " " + _("for Company") + " " + self.doc.company), raise_exception=True)
-
- return stock_in_hand_account
+ def get_default_account(self, account_for):
+ account = webnotes.conn.get_value("Company", self.doc.company, account_for)
+ if not account:
+ msgprint(_("Please mention default account for '") +
+ _(webnotes.get_doctype("company").get_label(account_for) +
+ _("' in Company: ") + self.doc.company), raise_exception=True)
+
+ return account
@property
def stock_items(self):
@@ -85,7 +92,7 @@
self._stock_items = [r[0] for r in webnotes.conn.sql("""select name
from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \
(", ".join((["%s"]*len(item_codes))),), item_codes)]
-
+
return self._stock_items
@property
@@ -93,4 +100,9 @@
if not hasattr(self, "_abbr"):
self._abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
- return self._abbr
\ No newline at end of file
+ return self._abbr
+
+
+@webnotes.whitelist()
+def get_default_account(account_for, company):
+ return webnotes.conn.get_value("Company", company, account_for)
diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py
index 2f3128c..2c2bb44 100644
--- a/controllers/buying_controller.py
+++ b/controllers/buying_controller.py
@@ -24,10 +24,11 @@
from setup.utils import get_company_currency
from webnotes.model.utils import round_floats_in_doc
-from controllers.accounts_controller import AccountsController
+from controllers.stock_controller import StockController
-class BuyingController(AccountsController):
- def validate(self):
+class BuyingController(StockController):
+ def validate(self):
+ super(BuyingController, self).validate()
if self.meta.get_field("currency"):
self.company_currency = get_company_currency(self.doc.company)
self.validate_conversion_rate("currency", "conversion_rate")
@@ -37,7 +38,7 @@
# IMPORTANT: enable this only when client side code is similar to this one
# self.calculate_taxes_and_totals()
-
+
# set total in words
self.set_total_in_words()
diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py
index 94a56e3..538c5c1 100644
--- a/controllers/selling_controller.py
+++ b/controllers/selling_controller.py
@@ -19,10 +19,11 @@
from webnotes.utils import cint
from setup.utils import get_company_currency
-from controllers.accounts_controller import AccountsController
+from controllers.stock_controller import StockController
-class SellingController(AccountsController):
+class SellingController(StockController):
def validate(self):
+ super(SellingController, self).validate()
self.set_total_in_words()
def set_total_in_words(self):
@@ -37,4 +38,25 @@
self.doc.grand_total or self.doc.rounded_total, company_currency)
if self.meta.get_field("in_words_export"):
self.doc.in_words_export = money_in_words(disable_rounded_total and
- self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
\ No newline at end of file
+ self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
+
+ def set_buying_amount(self):
+ from stock.utils import get_buying_amount
+ stock_ledger_entries = self.get_stock_ledger_entries()
+
+ item_sales_bom = {}
+ for d in self.doclist.get({"parentfield": "packing_details"}):
+ new_d = webnotes._dict(d.fields.copy())
+ new_d.total_qty = -1 * d.qty
+ item_sales_bom.setdefault(d.parent_item, []).append(new_d)
+
+ if stock_ledger_entries:
+ for item in self.doclist.get({"parentfield": self.fname}):
+ if item.item_code in self.stock_items or \
+ (item_sales_bom and item_sales_bom.get(item.item_code)):
+ buying_amount = get_buying_amount(item.item_code, item.warehouse, -1*item.qty,
+ self.doc.doctype, self.doc.name, item.name, stock_ledger_entries,
+ item_sales_bom)
+ item.buying_amount = buying_amount > 0 and buying_amount or 0
+ webnotes.conn.set_value(self.tname, item.name, "buying_amount",
+ item.buying_amount)
\ No newline at end of file
diff --git a/controllers/stock_controller.py b/controllers/stock_controller.py
new file mode 100644
index 0000000..c76865d
--- /dev/null
+++ b/controllers/stock_controller.py
@@ -0,0 +1,79 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes import msgprint, _
+from controllers.accounts_controller import AccountsController
+
+class StockController(AccountsController):
+ def get_gl_entries_for_stock(self, against_stock_account, amount,
+ stock_in_hand_account=None, cost_center=None):
+ if not stock_in_hand_account:
+ stock_in_hand_account = self.get_default_account("stock_in_hand_account")
+
+ if amount:
+ gl_entries = [
+ # stock in hand account
+ self.get_gl_dict({
+ "account": stock_in_hand_account,
+ "against": against_stock_account,
+ "debit": amount,
+ "remarks": self.doc.remarks or "Accounting Entry for Stock",
+ }, self.doc.docstatus == 2),
+
+ # account against stock in hand
+ self.get_gl_dict({
+ "account": against_stock_account,
+ "against": stock_in_hand_account,
+ "credit": amount,
+ "cost_center": cost_center or None,
+ "remarks": self.doc.remarks or "Accounting Entry for Stock",
+ }, self.doc.docstatus == 2),
+ ]
+
+ return gl_entries
+
+
+ def check_expense_account(self, item):
+ if not item.expense_account:
+ msgprint(_("""Expense account is mandatory for item: """) + item.item_code,
+ raise_exception=1)
+
+ def get_stock_ledger_entries(self, item_list=None, warehouse_list=None):
+ if not (item_list and warehouse_list):
+ item_list, warehouse_list = self.get_distinct_item_warehouse()
+
+ if item_list and warehouse_list:
+ return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
+ voucher_detail_no, posting_date, posting_time, stock_value,
+ warehouse, actual_qty as qty from `tabStock Ledger Entry`
+ where ifnull(`is_cancelled`, "No") = "No" and company = %s
+ and item_code in (%s) and warehouse in (%s)
+ order by item_code desc, warehouse desc, posting_date desc,
+ posting_time desc, name desc""" %
+ ('%s', ', '.join(['%s']*len(item_list)), ', '.join(['%s']*len(warehouse_list))),
+ tuple([self.doc.company] + item_list + warehouse_list), as_dict=1)
+
+ def get_distinct_item_warehouse(self):
+ item_list = []
+ warehouse_list = []
+ for item in self.doclist.get({"parentfield": self.fname}) \
+ + self.doclist.get({"parentfield": "packing_details"}):
+ item_list.append(item.item_code)
+ warehouse_list.append(item.warehouse)
+
+ return list(set(item_list)), list(set(warehouse_list))
\ No newline at end of file
diff --git a/home/page/attributions/attributions.html b/home/page/attributions/attributions.html
index 07da9fd..2d08c79 100644
--- a/home/page/attributions/attributions.html
+++ b/home/page/attributions/attributions.html
@@ -27,6 +27,10 @@
<td>The Number One HTTP Server On The Internet.</td>
</tr>
<tr>
+ <td><a href="http://memcached.org/">Memcached</a></td>
+ <td>Free & open source, high-performance, distributed memory object caching system.</td>
+ </tr>
+ <tr>
<td><a href="http://python.org/">Python Programming Language</a></td>
<td>The "batteries included" language that lets you write elegant code, quickly.<br><br>Python Libraries:
<ul>
diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js
index b387aad..183352c 100644
--- a/home/page/latest_updates/latest_updates.js
+++ b/home/page/latest_updates/latest_updates.js
@@ -1,6 +1,16 @@
erpnext.updates = [
+ ["19th March", ["Sales and Purchase Return Tool deprecated. Use Stock Entry instead."]],
+ ["12th March", ["Updates to website module. Added more options in Style Settings and Website Settings."]],
+ ["5th March", ["Refactored Upload Attendance Tool"]],
+ ["4th March", ["Lead organization added in Quotation classic/spartan/modern print format"]],
["1st March", [
- "Time Log, Time Log Batch: Created feature to batch Time Logs so that they can be tracked for billing."
+ "Time Log, Time Log Batch: Created feature to batch Time Logs so that they can be tracked for billing.",
+ "Sub-contracting code refactored for PO",
+ ]],
+ ["28th February", [
+ "Datatype validation in Voucher Import Tool",
+ "Fixes for conversion factor in old invoices",
+ "Fixed asynchronus issue in purchase cycle"
]],
["27th February", [
"Time Log: Created Time Log System, with Calendar View."
diff --git a/hr/doctype/appraisal_goal/appraisal_goal.txt b/hr/doctype/appraisal_goal/appraisal_goal.txt
index 7df60c1..ed71e69 100644
--- a/hr/doctype/appraisal_goal/appraisal_goal.txt
+++ b/hr/doctype/appraisal_goal/appraisal_goal.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:13",
+ "creation": "2013-02-22 01:27:44",
"docstatus": 0,
- "modified": "2013-01-22 14:16:18",
+ "modified": "2013-03-07 07:03:18",
"modified_by": "Administrator",
"owner": "ashwini@webnotestech.com"
},
@@ -33,6 +33,7 @@
"label": "Goal",
"oldfieldname": "kra",
"oldfieldtype": "Small Text",
+ "print_width": "240px",
"reqd": 1,
"width": "240px"
},
@@ -43,6 +44,7 @@
"label": "Weightage (%)",
"oldfieldname": "per_weightage",
"oldfieldtype": "Currency",
+ "print_width": "70px",
"reqd": 1,
"width": "70px"
},
@@ -56,6 +58,7 @@
"oldfieldname": "score",
"oldfieldtype": "Select",
"options": "\n0\n1\n2\n3\n4\n5",
+ "print_width": "70px",
"width": "70px"
},
{
@@ -66,6 +69,7 @@
"no_copy": 1,
"oldfieldname": "score_earned",
"oldfieldtype": "Currency",
+ "print_width": "70px",
"read_only": 1,
"width": "70px"
}
diff --git a/hr/doctype/appraisal_template_goal/appraisal_template_goal.txt b/hr/doctype/appraisal_template_goal/appraisal_template_goal.txt
index 59d0e8d..da9fde0 100644
--- a/hr/doctype/appraisal_template_goal/appraisal_template_goal.txt
+++ b/hr/doctype/appraisal_template_goal/appraisal_template_goal.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:13",
+ "creation": "2013-02-22 01:27:44",
"docstatus": 0,
- "modified": "2013-01-22 13:35:58",
+ "modified": "2013-03-07 07:03:18",
"modified_by": "Administrator",
"owner": "ashwini@webnotestech.com"
},
@@ -34,6 +34,7 @@
"label": "KRA",
"oldfieldname": "kra",
"oldfieldtype": "Small Text",
+ "print_width": "200px",
"width": "200px"
},
{
@@ -43,6 +44,7 @@
"label": "Weightage (%)",
"oldfieldname": "per_weightage",
"oldfieldtype": "Currency",
+ "print_width": "100px",
"width": "100px"
}
]
\ No newline at end of file
diff --git a/hr/doctype/employee_education/employee_education.txt b/hr/doctype/employee_education/employee_education.txt
index dd07df8..46b6f00 100644
--- a/hr/doctype/employee_education/employee_education.txt
+++ b/hr/doctype/employee_education/employee_education.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:35:54",
+ "creation": "2013-02-22 01:27:45",
"docstatus": 0,
- "modified": "2012-03-27 14:35:54",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "HR",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 5
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -42,6 +39,7 @@
"label": "Qualification",
"oldfieldname": "qualification",
"oldfieldtype": "Data",
+ "print_width": "100px",
"width": "100px"
},
{
diff --git a/hr/doctype/employee_external_work_history/employee_external_work_history.txt b/hr/doctype/employee_external_work_history/employee_external_work_history.txt
index eea7d65..05fc5c0 100644
--- a/hr/doctype/employee_external_work_history/employee_external_work_history.txt
+++ b/hr/doctype/employee_external_work_history/employee_external_work_history.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:14",
+ "creation": "2013-02-22 01:27:45",
"docstatus": 0,
- "modified": "2013-01-29 16:27:51",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/hr/doctype/employee_internal_work_history/employee_internal_work_history.txt b/hr/doctype/employee_internal_work_history/employee_internal_work_history.txt
index dd1c11f..d813e7c 100644
--- a/hr/doctype/employee_internal_work_history/employee_internal_work_history.txt
+++ b/hr/doctype/employee_internal_work_history/employee_internal_work_history.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:35:57",
+ "creation": "2013-02-22 01:27:45",
"docstatus": 0,
- "modified": "2012-03-27 14:35:57",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "HR",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 6
+ "name": "__common__"
},
{
"doctype": "DocField",
diff --git a/hr/doctype/employee_training/employee_training.txt b/hr/doctype/employee_training/employee_training.txt
index 256a99e..6b3a754 100644
--- a/hr/doctype/employee_training/employee_training.txt
+++ b/hr/doctype/employee_training/employee_training.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:35:59",
+ "creation": "2013-02-22 01:27:45",
"docstatus": 0,
- "modified": "2012-03-27 14:35:59",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "HR",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 5
+ "name": "__common__"
},
{
"doctype": "DocField",
diff --git a/hr/doctype/expense_claim_detail/expense_claim_detail.txt b/hr/doctype/expense_claim_detail/expense_claim_detail.txt
index d8f9400..d2b5cf3 100644
--- a/hr/doctype/expense_claim_detail/expense_claim_detail.txt
+++ b/hr/doctype/expense_claim_detail/expense_claim_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:14",
+ "creation": "2013-02-22 01:27:46",
"docstatus": 0,
- "modified": "2013-01-29 16:27:51",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "harshada@webnotestech.com"
},
@@ -31,6 +31,7 @@
"label": "Expense Date",
"oldfieldname": "expense_date",
"oldfieldtype": "Date",
+ "print_width": "150px",
"reqd": 0,
"width": "150px"
},
@@ -42,6 +43,7 @@
"oldfieldname": "expense_type",
"oldfieldtype": "Link",
"options": "link:Expense Claim Type",
+ "print_width": "150px",
"reqd": 1,
"width": "150px"
},
@@ -52,6 +54,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Small Text",
+ "print_width": "300px",
"width": "300px"
},
{
@@ -62,6 +65,7 @@
"oldfieldname": "claim_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
+ "print_width": "150px",
"reqd": 1,
"width": "150px"
},
@@ -75,6 +79,7 @@
"oldfieldname": "sanctioned_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
+ "print_width": "150px",
"width": "150px"
}
]
\ No newline at end of file
diff --git a/hr/doctype/holiday/holiday.txt b/hr/doctype/holiday/holiday.txt
index 734b970..94f7936 100644
--- a/hr/doctype/holiday/holiday.txt
+++ b/hr/doctype/holiday/holiday.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:35:57",
+ "creation": "2013-02-22 01:27:46",
"docstatus": 0,
- "modified": "2012-03-27 14:35:57",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "HR",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 2
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -32,6 +29,7 @@
"fieldname": "description",
"fieldtype": "Small Text",
"label": "Description",
+ "print_width": "300px",
"width": "300px"
},
{
diff --git a/hr/doctype/leave_block_list_allow/leave_block_list_allow.txt b/hr/doctype/leave_block_list_allow/leave_block_list_allow.txt
index 4d73833..8e362f3 100644
--- a/hr/doctype/leave_block_list_allow/leave_block_list_allow.txt
+++ b/hr/doctype/leave_block_list_allow/leave_block_list_allow.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-14 17:37:38",
+ "creation": "2013-02-22 01:27:47",
"docstatus": 0,
- "modified": "2013-02-14 17:41:53",
+ "modified": "2013-03-07 07:03:23",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -23,6 +23,7 @@
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
+ "print_width": "200px",
"reqd": 1,
"width": "200px"
},
diff --git a/hr/doctype/leave_block_list_date/leave_block_list_date.txt b/hr/doctype/leave_block_list_date/leave_block_list_date.txt
index 7c7ef38..d0b9fbf 100644
--- a/hr/doctype/leave_block_list_date/leave_block_list_date.txt
+++ b/hr/doctype/leave_block_list_date/leave_block_list_date.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-14 17:37:38",
+ "creation": "2013-02-22 01:27:47",
"docstatus": 0,
- "modified": "2013-02-14 17:41:44",
+ "modified": "2013-03-07 07:03:23",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -19,6 +19,7 @@
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
+ "print_width": "200px",
"reqd": 1,
"width": "200px"
},
diff --git a/hr/doctype/other_income_detail/other_income_detail.txt b/hr/doctype/other_income_detail/other_income_detail.txt
index 0913e4c..b647ee7 100644
--- a/hr/doctype/other_income_detail/other_income_detail.txt
+++ b/hr/doctype/other_income_detail/other_income_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:15",
+ "creation": "2013-02-22 01:27:47",
"docstatus": 0,
- "modified": "2013-01-22 14:56:40",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -44,6 +44,7 @@
"label": "Particulars",
"oldfieldname": "particulars2",
"oldfieldtype": "Small Text",
+ "print_width": "200px",
"read_only": 1,
"reqd": 1,
"width": "200px"
diff --git a/hr/doctype/salary_slip_deduction/salary_slip_deduction.txt b/hr/doctype/salary_slip_deduction/salary_slip_deduction.txt
index 958147c..86acef0 100644
--- a/hr/doctype/salary_slip_deduction/salary_slip_deduction.txt
+++ b/hr/doctype/salary_slip_deduction/salary_slip_deduction.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:15",
+ "creation": "2013-02-22 01:27:48",
"docstatus": 0,
- "modified": "2013-01-29 16:27:52",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -46,6 +46,7 @@
"oldfieldname": "d_type",
"oldfieldtype": "Data",
"options": "Deduction Type",
+ "print_width": "200px",
"width": "200px"
},
{
diff --git a/hr/doctype/salary_slip_earning/salary_slip_earning.txt b/hr/doctype/salary_slip_earning/salary_slip_earning.txt
index e0acf29..64f4dc6 100644
--- a/hr/doctype/salary_slip_earning/salary_slip_earning.txt
+++ b/hr/doctype/salary_slip_earning/salary_slip_earning.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:15",
+ "creation": "2013-02-22 01:27:48",
"docstatus": 0,
- "modified": "2013-01-29 16:27:52",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -46,6 +46,7 @@
"oldfieldname": "e_type",
"oldfieldtype": "Data",
"options": "Earning Type",
+ "print_width": "200px",
"width": "200px"
},
{
diff --git a/hr/doctype/salary_structure_deduction/salary_structure_deduction.txt b/hr/doctype/salary_structure_deduction/salary_structure_deduction.txt
index 1591b0f..53dbf69 100644
--- a/hr/doctype/salary_structure_deduction/salary_structure_deduction.txt
+++ b/hr/doctype/salary_structure_deduction/salary_structure_deduction.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:16",
+ "creation": "2013-02-22 01:27:48",
"docstatus": 0,
- "modified": "2013-01-29 16:27:52",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -32,6 +32,7 @@
"oldfieldname": "d_type",
"oldfieldtype": "Select",
"options": "Deduction Type",
+ "print_width": "200px",
"reqd": 1,
"width": "200px"
},
diff --git a/hr/doctype/salary_structure_earning/salary_structure_earning.txt b/hr/doctype/salary_structure_earning/salary_structure_earning.txt
index 74f6fe2..29c3f52 100644
--- a/hr/doctype/salary_structure_earning/salary_structure_earning.txt
+++ b/hr/doctype/salary_structure_earning/salary_structure_earning.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:16",
+ "creation": "2013-02-22 01:27:48",
"docstatus": 0,
- "modified": "2013-01-29 16:27:52",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -34,6 +34,7 @@
"oldfieldname": "e_type",
"oldfieldtype": "Data",
"options": "Earning Type",
+ "print_width": "200px",
"reqd": 1,
"width": "200px"
},
diff --git a/hr/doctype/upload_attendance/upload_attendance.js b/hr/doctype/upload_attendance/upload_attendance.js
index 008e1cd..0c1d7b2 100644
--- a/hr/doctype/upload_attendance/upload_attendance.js
+++ b/hr/doctype/upload_attendance/upload_attendance.js
@@ -18,7 +18,7 @@
wn.require("public/app/js/utils.js");
wn.provide("erpnext.hr");
-erpnext.hr.AttendanceControlPanel = erpnext.utils.Controller.extend({
+erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({
onload: function() {
this.frm.set_value("att_fr_date", get_today());
this.frm.set_value("att_to_date", get_today());
diff --git a/hr/search_criteria/monthly_attendance_details/monthly_attendance_details.sql b/hr/search_criteria/monthly_attendance_details/monthly_attendance_details.sql
index 7487fb4..762a94f 100644
--- a/hr/search_criteria/monthly_attendance_details/monthly_attendance_details.sql
+++ b/hr/search_criteria/monthly_attendance_details/monthly_attendance_details.sql
@@ -1 +1 @@
-SELECT DISTINCT `tabAttendance`.employee, `tabAttendance`.employee_name FROM `tabAttendance` WHERE `tabAttendance`.fiscal_year like '%(fiscal_year)s%%' AND `tabAttendance`.`company` like '%(company)s%%' AND `tabAttendance`.`employee` like '%(employee)s%%'
\ No newline at end of file
+SELECT DISTINCT `tabAttendance`.employee, `tabEmployee`.employee_name FROM `tabAttendance`, `tabEmployee` WHERE `tabEmployee`.name = `tabAttendance`.employee and `tabAttendance`.fiscal_year like '%(fiscal_year)s%%' AND `tabAttendance`.company like '%(company)s%%' AND `tabAttendance`.employee like '%(employee)s%%'
\ No newline at end of file
diff --git a/hr/search_criteria/monthly_salary_register/monthly_salary_register.py b/hr/search_criteria/monthly_salary_register/monthly_salary_register.py
index 5171aa4..2291b66 100644
--- a/hr/search_criteria/monthly_salary_register/monthly_salary_register.py
+++ b/hr/search_criteria/monthly_salary_register/monthly_salary_register.py
@@ -38,8 +38,8 @@
for r in res:
- total_lwp += r[col_idx['Leave Without Pay']]
- total_arr += r[col_idx['Arrear Amount']]
+ total_lwp += flt(r[col_idx['Leave Without Pay']])
+ total_arr += flt(r[col_idx['Arrear Amount']])
for d1 in li:
d2 = '%s'%d1
diff --git a/manufacturing/doctype/bom_explosion_item/bom_explosion_item.txt b/manufacturing/doctype/bom_explosion_item/bom_explosion_item.txt
index fb09611..07aad7d 100644
--- a/manufacturing/doctype/bom_explosion_item/bom_explosion_item.txt
+++ b/manufacturing/doctype/bom_explosion_item/bom_explosion_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:16",
+ "creation": "2013-02-22 01:27:48",
"docstatus": 0,
- "modified": "2013-01-23 16:43:10",
+ "modified": "2013-03-07 07:03:18",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -44,6 +44,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "300px",
"width": "300px"
},
{
@@ -88,6 +89,7 @@
"oldfieldname": "parent_bom",
"oldfieldtype": "Link",
"options": "BOM",
+ "print_width": "250px",
"width": "250px"
},
{
diff --git a/manufacturing/doctype/bom_item/bom_item.txt b/manufacturing/doctype/bom_item/bom_item.txt
index 1da7f0d..14be95a 100644
--- a/manufacturing/doctype/bom_item/bom_item.txt
+++ b/manufacturing/doctype/bom_item/bom_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:16",
+ "creation": "2013-02-22 01:27:49",
"docstatus": 0,
- "modified": "2013-01-23 16:43:11",
+ "modified": "2013-03-07 07:03:18",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -67,6 +67,7 @@
"oldfieldname": "bom_no",
"oldfieldtype": "Link",
"options": "BOM",
+ "print_width": "150px",
"reqd": 0,
"search_index": 1,
"width": "150px"
@@ -103,6 +104,7 @@
"label": "Amount",
"oldfieldname": "amount_as_per_mar",
"oldfieldtype": "Currency",
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
},
@@ -122,6 +124,7 @@
"label": "Item Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "250px",
"reqd": 0,
"width": "250px"
},
diff --git a/manufacturing/doctype/bom_operation/bom_operation.txt b/manufacturing/doctype/bom_operation/bom_operation.txt
index e722bbe..56805b5 100644
--- a/manufacturing/doctype/bom_operation/bom_operation.txt
+++ b/manufacturing/doctype/bom_operation/bom_operation.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:16",
+ "creation": "2013-02-22 01:27:49",
"docstatus": 0,
- "modified": "2013-01-23 16:43:12",
+ "modified": "2013-03-07 07:03:19",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/manufacturing/doctype/production_plan_item/production_plan_item.txt b/manufacturing/doctype/production_plan_item/production_plan_item.txt
index a2f9367..3af1bea 100644
--- a/manufacturing/doctype/production_plan_item/production_plan_item.txt
+++ b/manufacturing/doctype/production_plan_item/production_plan_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-19 10:23:34",
+ "creation": "2013-02-22 01:27:49",
"docstatus": 0,
- "modified": "2013-01-22 14:00:34",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -33,6 +33,7 @@
"oldfieldname": "item_code",
"oldfieldtype": "Link",
"options": "Item",
+ "print_width": "150px",
"reqd": 1,
"width": "150px"
},
@@ -44,6 +45,7 @@
"oldfieldname": "bom_no",
"oldfieldtype": "Link",
"options": "BOM",
+ "print_width": "100px",
"reqd": 1,
"width": "100px"
},
@@ -55,6 +57,7 @@
"label": "Planned Qty",
"oldfieldname": "planned_qty",
"oldfieldtype": "Currency",
+ "print_width": "100px",
"reqd": 1,
"width": "100px"
},
@@ -76,6 +79,7 @@
"label": "SO Pending Qty",
"oldfieldname": "prevdoc_reqd_qty",
"oldfieldtype": "Currency",
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"width": "100px"
@@ -87,6 +91,7 @@
"label": "UOM",
"oldfieldname": "stock_uom",
"oldfieldtype": "Data",
+ "print_width": "80px",
"read_only": 1,
"reqd": 1,
"width": "80px"
@@ -98,6 +103,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "200px",
"read_only": 1,
"width": "200px"
}
diff --git a/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.txt b/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.txt
index 9c2b132..dc5b88d 100644
--- a/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.txt
+++ b/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:17",
+ "creation": "2013-02-22 01:27:49",
"docstatus": 0,
- "modified": "2013-01-29 16:27:52",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -46,6 +46,7 @@
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Data",
"options": "Sales Order",
+ "print_width": "150px",
"width": "150px"
},
{
@@ -55,6 +56,7 @@
"label": "SO Date",
"oldfieldname": "document_date",
"oldfieldtype": "Date",
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
},
@@ -64,6 +66,7 @@
"fieldtype": "Link",
"label": "Customer",
"options": "Customer",
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
},
@@ -73,6 +76,7 @@
"fieldtype": "Currency",
"label": "Grand Total",
"options": "Company:company:default_currency",
+ "print_width": "120px",
"read_only": 1,
"width": "120px"
},
diff --git a/patches/december_2012/clear_web_cache.py b/patches/december_2012/clear_web_cache.py
deleted file mode 100644
index b92f4bd..0000000
--- a/patches/december_2012/clear_web_cache.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import webnotes
-def execute():
- webnotes.reload_doc("website", "doctype", "web_page")
- webnotes.reload_doc("website", "doctype", "blog")
- webnotes.reload_doc("stock", "doctype", "item")
- webnotes.reload_doc("setup", "doctype", "item_group")
-
- # build wn-web.js and wn-web.css
- from website.helpers.make_web_include_files import make
- make()
-
- import website.utils
- website.utils.clear_cache()
\ No newline at end of file
diff --git a/patches/february_2013/p07_clear_web_cache.py b/patches/february_2013/p07_clear_web_cache.py
deleted file mode 100644
index 5aca2d6..0000000
--- a/patches/february_2013/p07_clear_web_cache.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import webnotes
-
-def execute():
- from website.utils import clear_cache
- clear_cache()
-
\ No newline at end of file
diff --git a/patches/march_2013/p03_rename_blog_to_blog_post.py b/patches/march_2013/p03_rename_blog_to_blog_post.py
new file mode 100644
index 0000000..69902f34
--- /dev/null
+++ b/patches/march_2013/p03_rename_blog_to_blog_post.py
@@ -0,0 +1,9 @@
+import webnotes
+
+def execute():
+ webnotes.reload_doc('website', 'doctype', 'blogger')
+ webnotes.rename_doc("DocType", "Blog", "Blog Post", force=True)
+ webnotes.reload_doc('website', 'doctype', 'blog_post')
+ webnotes.conn.sql('''update tabBlogger set posts=(select count(*)
+ from `tabBlog Post` where ifnull(blogger,"")=tabBlogger.name)''')
+ webnotes.conn.sql("""update `tabBlog Post` set published_on=date(creation)""")
diff --git a/patches/march_2013/p03_update_buying_amount.py b/patches/march_2013/p03_update_buying_amount.py
new file mode 100644
index 0000000..e45a3db
--- /dev/null
+++ b/patches/march_2013/p03_update_buying_amount.py
@@ -0,0 +1,10 @@
+import webnotes
+
+def execute():
+ dn_list = webnotes.conn.sql("""select name from `tabDelivery Note` where docstatus < 2""")
+ for dn in dn_list:
+ webnotes.bean("Delivery Note", dn[0]).set_buying_amount()
+
+ si_list = webnotes.conn.sql("""select name from `tabSales Invoice` where docstatus < 2""")
+ for si in si_list:
+ webnotes.bean("Sales Invoice", si[0]).set_buying_amount()
\ No newline at end of file
diff --git a/patches/march_2013/p04_pos_update_stock_check.py b/patches/march_2013/p04_pos_update_stock_check.py
new file mode 100644
index 0000000..da48efe
--- /dev/null
+++ b/patches/march_2013/p04_pos_update_stock_check.py
@@ -0,0 +1,18 @@
+import webnotes
+
+def execute():
+ from webnotes.utils import cint
+ webnotes.reload_doc("setup", "doctype", "global_defaults")
+
+ doctype_list = webnotes.get_doctype("Sales Invoice")
+ update_stock_df = doctype_list.get_field("update_stock")
+
+ global_defaults = webnotes.bean("Global Defaults", "Global Defaults")
+ global_defaults.doc.update_stock = cint(update_stock_df.default)
+ global_defaults.save()
+
+ webnotes.conn.sql("""delete from `tabProperty Setter`
+ where doc_type='Sales Invoice' and doctype_or_field='DocField'
+ and field_name='update_stock' and property='default'""")
+
+ webnotes.reload_doc("accounts", "doctype", "sales_invoice")
\ No newline at end of file
diff --git a/patches/march_2013/p05_payment_reconciliation.py b/patches/march_2013/p05_payment_reconciliation.py
new file mode 100644
index 0000000..7b6306b
--- /dev/null
+++ b/patches/march_2013/p05_payment_reconciliation.py
@@ -0,0 +1,29 @@
+import webnotes
+
+def execute():
+ # delete wrong gle entries created due to a bug in make_gl_entries of Account Controller
+ # when using payment reconciliation
+ res = webnotes.conn.sql_list("""select distinct gl1.voucher_no
+ from `tabGL Entry` gl1, `tabGL Entry` gl2
+ where
+ date(gl1.modified) >= "2013-03-11"
+ and date(gl1.modified) = date(gl2.modified)
+ and gl1.voucher_no = gl2.voucher_no
+ and gl1.voucher_type = "Journal Voucher"
+ and gl1.voucher_type = gl2.voucher_type
+ and gl1.posting_date = gl2.posting_date
+ and gl1.account = gl2.account
+ and ifnull(gl1.is_cancelled, 'No') = 'No' and ifnull(gl2.is_cancelled, 'No') = 'No'
+ and ifnull(gl1.against_voucher, '') = ifnull(gl2.against_voucher, '')
+ and ifnull(gl1.against_voucher_type, '') = ifnull(gl2.against_voucher_type, '')
+ and gl1.remarks = gl2.remarks
+ and ifnull(gl1.debit, 0) = ifnull(gl2.credit, 0)
+ and ifnull(gl1.credit, 0) = ifnull(gl2.debit, 0)
+ and gl1.name > gl2.name""")
+
+ for r in res:
+ webnotes.conn.sql("""update `tabGL Entry` set `is_cancelled`='Yes'
+ where voucher_type='Journal Voucher' and voucher_no=%s""", r)
+ jv = webnotes.bean("Journal Voucher", r)
+ jv.run_method("make_gl_entries")
+
\ No newline at end of file
diff --git a/patches/march_2013/p06_remove_sales_purchase_return_tool.py b/patches/march_2013/p06_remove_sales_purchase_return_tool.py
new file mode 100644
index 0000000..e907e4a
--- /dev/null
+++ b/patches/march_2013/p06_remove_sales_purchase_return_tool.py
@@ -0,0 +1,5 @@
+import webnotes
+
+def execute():
+ webnotes.delete_doc("DocType", "Sales and Purchase Return Item")
+ webnotes.delete_doc("DocType", "Sales and Purchase Return Tool")
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index d6b8f18..9c0d9b8 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -16,6 +16,9 @@
from __future__ import unicode_literals
patch_list = [
+ "execute:webnotes.reload_doc('core', 'doctype', 'docfield')",
+ "execute:webnotes.reload_doc('core', 'doctype', 'report')",
+ "execute:webnotes.reload_doc('core', 'doctype', 'doctype')",
"patches.mar_2012.so_rv_mapper_fix",
"patches.mar_2012.clean_property_setter",
"patches.april_2012.naming_series_patch",
@@ -129,7 +132,6 @@
"patches.december_2012.fix_default_print_format",
"patches.december_2012.file_list_rename",
"patches.december_2012.replace_createlocal",
- "patches.december_2012.clear_web_cache",
"patches.december_2012.remove_quotation_next_contact",
"patches.december_2012.stock_entry_cleanup",
"patches.december_2012.production_order_naming_series",
@@ -186,7 +188,6 @@
"execute:webnotes.delete_doc('DocType', 'Service Order Detail')",
"execute:webnotes.delete_doc('DocType', 'Service Quotation Detail')",
"patches.february_2013.p06_material_request_mappers",
- "patches.february_2013.p07_clear_web_cache",
"execute:webnotes.delete_doc('Page', 'Query Report')",
"execute:webnotes.delete_doc('Search Criteria', 'employeewise_balance_leave_report')",
"execute:webnotes.delete_doc('Search Criteria', 'employee_leave_balance_report')",
@@ -208,4 +209,10 @@
"execute:webnotes.conn.sql('update tabDocPerm set `submit`=1, `cancel`=1, `amend`=1 where parent=\"Time Log\"')",
"execute:webnotes.delete_doc('DocType', 'Attendance Control Panel')",
"patches.march_2013.p02_get_global_default",
+ "patches.march_2013.p03_rename_blog_to_blog_post",
+ "execute:webnotes.reload_doc('hr', 'search_criteria', 'monthly_attendance_details')",
+ "patches.march_2013.p04_pos_update_stock_check",
+ "patches.march_2013.p05_payment_reconciliation",
+ "patches.march_2013.p06_remove_sales_purchase_return_tool",
+ "execute:webnotes.bean('Global Defaults').save()"
]
\ No newline at end of file
diff --git a/projects/doctype/project_milestone/project_milestone.txt b/projects/doctype/project_milestone/project_milestone.txt
index 4641b5d..11c5d20 100644
--- a/projects/doctype/project_milestone/project_milestone.txt
+++ b/projects/doctype/project_milestone/project_milestone.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:06",
+ "creation": "2013-02-22 01:27:50",
"docstatus": 0,
- "modified": "2012-03-27 14:36:06",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,9 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Projects",
- "name": "__common__",
- "section_style": "Simple",
- "version": 4
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -41,6 +39,7 @@
"label": "Milestone",
"oldfieldname": "milestone",
"oldfieldtype": "Text",
+ "print_width": "300px",
"width": "300px"
},
{
diff --git a/projects/doctype/task/task.js b/projects/doctype/task/task.js
index 472ca6b..8493920 100644
--- a/projects/doctype/task/task.js
+++ b/projects/doctype/task/task.js
@@ -18,7 +18,7 @@
cur_frm.add_fetch("project", "company", "company");
-erpnext.projects.Task = erpnext.utils.Controller.extend({
+erpnext.projects.Task = wn.ui.form.Controller.extend({
setup: function() {
this.frm.fields_dict.project.get_query = function() {
return "select name from `tabProject` \
@@ -29,7 +29,8 @@
project: function() {
if(this.frm.doc.project) {
- get_server_fields('get_project_details', '','', doc, cdt, cdn, 1);
+ get_server_fields('get_project_details', '','', this.frm.doc, this.frm.doc.doctype,
+ this.frm.doc.name, 1);
}
},
diff --git a/projects/doctype/time_log_batch_detail/time_log_batch_detail.txt b/projects/doctype/time_log_batch_detail/time_log_batch_detail.txt
index d1e1eae..8bd554f 100644
--- a/projects/doctype/time_log_batch_detail/time_log_batch_detail.txt
+++ b/projects/doctype/time_log_batch_detail/time_log_batch_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-28 17:56:12",
+ "creation": "2013-03-05 09:11:06",
"docstatus": 0,
- "modified": "2013-03-01 15:20:17",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -30,6 +30,7 @@
"fieldtype": "Link",
"label": "Time Log",
"options": "Time Log",
+ "print_width": "200px",
"reqd": 1,
"width": "200px"
},
diff --git a/public/js/controllers/stock_controller.js b/public/js/controllers/stock_controller.js
index d3511e1..15d34e0 100644
--- a/public/js/controllers/stock_controller.js
+++ b/public/js/controllers/stock_controller.js
@@ -16,7 +16,7 @@
wn.provide("erpnext.stock");
-erpnext.stock.StockController = erpnext.utils.Controller.extend({
+erpnext.stock.StockController = wn.ui.form.Controller.extend({
show_stock_ledger: function() {
var me = this;
this.frm.add_custom_button("Show Stock Ledger", function() {
diff --git a/public/js/feature_setup.js b/public/js/feature_setup.js
index 0304034..85c848d 100644
--- a/public/js/feature_setup.js
+++ b/public/js/feature_setup.js
@@ -166,22 +166,24 @@
'Address': {'fields':['sales_partner']},
'Contact': {'fields':['sales_partner']},
'Customer': {'fields':['sales_team']},
- 'Delivery Note': {'fields':['sales_team','Packing List']},
+ 'Delivery Note': {'fields':['sales_team','packing_list']},
'Item': {'fields':['item_customer_details']},
- 'Sales Invoice': {'fields':['sales_team']},
- 'Sales Order': {'fields':['sales_team','Packing List']}
+ 'Sales Invoice': {'fields':['sales_team', 'packing_list']},
+ 'Sales Order': {'fields':['sales_team','packing_list']}
},
'fs_more_info': {
- 'Delivery Note': {'fields':['More Info']},
- 'Opportunity': {'fields':['More Info']},
- 'Material Request': {'fields':['More Info']},
- 'Lead': {'fields':['More Info']},
- 'Purchase Invoice': {'fields':['More Info']},
- 'Purchase Order': {'fields':['More Info']},
- 'Purchase Receipt': {'fields':['More Info']},
- 'Quotation': {'fields':['More Info']},
- 'Sales Invoice': {'fields':['More Info']},
- 'Sales Order': {'fields':['More Info']},
+ "Customer Issue": {"fields": ["more_info"]},
+ 'Material Request': {'fields':['more_info']},
+ 'Lead': {'fields':['more_info']},
+ 'Opportunity': {'fields':['more_info']},
+ 'Purchase Invoice': {'fields':['more_info']},
+ 'Purchase Order': {'fields':['more_info']},
+ 'Purchase Receipt': {'fields':['more_info']},
+ 'Supplier Quotation': {'fields':['more_info']},
+ 'Quotation': {'fields':['more_info']},
+ 'Sales Invoice': {'fields':['more_info']},
+ 'Sales Order': {'fields':['more_info']},
+ 'Delivery Note': {'fields':['more_info']},
},
'fs_quality': {
'Item': {'fields':['Item Inspection Criteria','inspection_required']},
@@ -199,25 +201,23 @@
}
$(document).bind('form_refresh', function() {
- for(sys_feat in sys_defaults)
- {
- if(sys_defaults[sys_feat]=='0' && (sys_feat in pscript.feature_dict)) //"Features to hide" exists
- {
- if(cur_frm.doc.doctype in pscript.feature_dict[sys_feat])
- {
- for(fort in pscript.feature_dict[sys_feat][cur_frm.doc.doctype])
- {
- if(fort=='fields')
+ for(sys_feat in sys_defaults) {
+ if(sys_defaults[sys_feat]=='0'
+ && (sys_feat in pscript.feature_dict)) { //"Features to hide" exists
+
+ if(cur_frm.doc.doctype in pscript.feature_dict[sys_feat]) {
+ for(fort in pscript.feature_dict[sys_feat][cur_frm.doc.doctype]) {
+ if(fort=='fields') {
hide_field(pscript.feature_dict[sys_feat][cur_frm.doc.doctype][fort]);
- else if(cur_frm.fields_dict[fort])
- {
+ } else if(cur_frm.fields_dict[fort]) {
for(grid_field in pscript.feature_dict[sys_feat][cur_frm.doc.doctype][fort])
cur_frm.fields_dict[fort].grid.set_column_disp(pscript.feature_dict[sys_feat][cur_frm.doc.doctype][fort][grid_field], false);
- }
- else
+ } else {
msgprint('Grid "'+fort+'" does not exists');
+ }
}
}
+
}
}
})
diff --git a/public/js/stock_analytics.js b/public/js/stock_analytics.js
index d6a994c..c3ed1cb 100644
--- a/public/js/stock_analytics.js
+++ b/public/js/stock_analytics.js
@@ -134,6 +134,7 @@
var data = wn.report_dump.data["Stock Ledger Entry"];
this.item_warehouse = {};
+ this.serialized_buying_rates = this.get_serialized_buying_rates();
for(var i=0, j=data.length; i<j; i++) {
var sl = data[i];
diff --git a/public/js/stock_grid_report.js b/public/js/stock_grid_report.js
index 2f81999..173eb21 100644
--- a/public/js/stock_grid_report.js
+++ b/public/js/stock_grid_report.js
@@ -44,8 +44,9 @@
wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
} else {
// outgoing
-
- if(is_fifo) {
+ if(sl.serial_no) {
+ var value_diff = -1 * this.get_serialized_value_diff(sl);
+ } else if(is_fifo) {
var value_diff = this.get_fifo_value_diff(wh, sl);
} else {
// average rate for weighted average
@@ -63,7 +64,7 @@
// update balance (only needed in case of valuation)
wh.balance_qty += sl.qty;
wh.balance_value += value_diff;
-
+
return value_diff;
},
get_fifo_value_diff: function(wh, sl) {
@@ -102,4 +103,34 @@
wh.fifo_stack = fifo_stack.reverse();
return -fifo_value_diff;
},
+
+ get_serialized_value_diff: function(sl) {
+ var me = this;
+
+ var value_diff = 0.0;
+
+ $.each(sl.serial_no.trim().split("\n"), function(i, sr) {
+ if(sr) {
+ value_diff += flt(me.serialized_buying_rates[sr.trim()]);
+ }
+ });
+
+ return value_diff;
+ },
+
+ get_serialized_buying_rates: function() {
+ var serialized_buying_rates = {};
+
+ $.each(wn.report_dump.data["Stock Ledger Entry"], function(i, sle) {
+ if(sle.qty > 0 && sle.serial_no) {
+ $.each(sle.serial_no.trim().split("\n"), function(i, sr) {
+ if(sr && sle.incoming_rate !== undefined) {
+ serialized_buying_rates[sr.trim()] = flt(sle.incoming_rate);
+ }
+ });
+ }
+ });
+
+ return serialized_buying_rates;
+ },
});
\ No newline at end of file
diff --git a/public/js/utils.js b/public/js/utils.js
index 0f78705..4df9555 100644
--- a/public/js/utils.js
+++ b/public/js/utils.js
@@ -23,35 +23,4 @@
return wn.model.get(":Company", company).default_currency || wn.boot.sysdefaults.currency;
else
return wn.boot.sysdefaults.currency;
-}
-
-// TODO
-erpnext.utils.Controller = Class.extend({
- init: function(opts) {
- $.extend(this, opts);
- this.setup && this.setup();
- },
-
- onload_post_render: function() {
- if(this.frm.doc.__islocal) {
- this.setup_defaults();
- }
- },
-
- setup_defaults: function() {
- var me = this;
-
- var defaults = {
- posting_date: wn.datetime.get_today(),
- posting_time: wn.datetime.now_time()
- }
-
- $.each(defaults, function(k, v) {
- if(!me.frm.doc[k]) me.frm.set_value(k, v);
- });
- },
-
- refresh: function() {
- erpnext.hide_naming_series();
- }
-});
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/selling/doctype/installation_note_item/installation_note_item.txt b/selling/doctype/installation_note_item/installation_note_item.txt
index 16f9bbc..a2ccdc4 100644
--- a/selling/doctype/installation_note_item/installation_note_item.txt
+++ b/selling/doctype/installation_note_item/installation_note_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:18",
+ "creation": "2013-02-22 01:27:51",
"docstatus": 0,
- "modified": "2013-01-22 14:47:00",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -42,6 +42,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Data",
+ "print_width": "300px",
"read_only": 1,
"width": "300px"
},
@@ -63,6 +64,7 @@
"label": "Serial No",
"oldfieldname": "serial_no",
"oldfieldtype": "Small Text",
+ "print_width": "180px",
"width": "180px"
},
{
@@ -75,6 +77,7 @@
"oldfieldname": "prevdoc_detail_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
},
@@ -89,6 +92,7 @@
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
@@ -104,6 +108,7 @@
"oldfieldname": "prevdoc_doctype",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py
index c336fe2..571cdfd 100644
--- a/selling/doctype/lead/lead.py
+++ b/selling/doctype/lead/lead.py
@@ -97,7 +97,6 @@
return webnotes.conn.get_value('Sales Email Settings',None,'email_id')
def on_trash(self):
- webnotes.conn.sql("""delete from tabCommunication where lead=%s""",
- self.doc.name)
+ webnotes.conn.sql("""update tabCommunication set lead=null where lead=%s""", self.doc.name)
webnotes.conn.sql("""update `tabSupport Ticket` set lead='' where lead=%s""",
self.doc.name)
diff --git a/selling/doctype/opportunity_item/opportunity_item.txt b/selling/doctype/opportunity_item/opportunity_item.txt
index f9f8c79..ba7870e 100644
--- a/selling/doctype/opportunity_item/opportunity_item.txt
+++ b/selling/doctype/opportunity_item/opportunity_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:19",
+ "creation": "2013-02-22 01:27:51",
"docstatus": 0,
- "modified": "2013-01-29 16:27:53",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -50,6 +50,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "300px",
"reqd": 1,
"width": "300px"
},
diff --git a/selling/doctype/quotation_item/quotation_item.txt b/selling/doctype/quotation_item/quotation_item.txt
index 8979562..dccc503 100644
--- a/selling/doctype/quotation_item/quotation_item.txt
+++ b/selling/doctype/quotation_item/quotation_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:19",
+ "creation": "2013-02-22 01:27:52",
"docstatus": 0,
- "modified": "2013-01-29 16:27:54",
+ "modified": "2013-03-07 07:03:29",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -36,6 +36,7 @@
"oldfieldtype": "Link",
"options": "Item",
"print_hide": 0,
+ "print_width": "150px",
"reqd": 1,
"search_index": 1,
"width": "150px"
@@ -58,6 +59,7 @@
"oldfieldname": "item_name",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"reqd": 1,
"search_index": 1,
"width": "150px"
@@ -70,6 +72,7 @@
"oldfieldname": "description",
"oldfieldtype": "Small Text",
"print_hide": 0,
+ "print_width": "300px",
"reqd": 1,
"width": "300px"
},
@@ -83,6 +86,7 @@
"oldfieldname": "qty",
"oldfieldtype": "Currency",
"print_hide": 0,
+ "print_width": "100px",
"reqd": 1,
"search_index": 0,
"width": "100px"
@@ -95,6 +99,7 @@
"oldfieldname": "stock_uom",
"oldfieldtype": "Data",
"print_hide": 0,
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"width": "100px"
@@ -109,6 +114,7 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 1,
+ "print_width": "100px",
"reqd": 0,
"width": "100px"
},
@@ -121,6 +127,7 @@
"oldfieldname": "adj_rate",
"oldfieldtype": "Float",
"print_hide": 1,
+ "print_width": "100px",
"width": "100px"
},
{
@@ -134,6 +141,7 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 0,
+ "print_width": "100px",
"reqd": 0,
"search_index": 0,
"width": "100px"
@@ -149,6 +157,7 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 0,
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"search_index": 0,
@@ -163,6 +172,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -177,6 +187,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"reqd": 0,
"search_index": 0,
"width": "100px"
@@ -192,6 +203,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"search_index": 0,
@@ -222,6 +234,7 @@
"oldfieldtype": "Link",
"options": "Brand",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
@@ -247,6 +260,7 @@
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"report_hide": 0,
"width": "150px"
@@ -261,6 +275,7 @@
"oldfieldname": "prevdoc_doctype",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"report_hide": 0,
"width": "150px"
diff --git a/selling/doctype/sales_and_purchase_return_item/__init__.py b/selling/doctype/sales_and_purchase_return_item/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/selling/doctype/sales_and_purchase_return_item/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/_messages_doc.json b/selling/doctype/sales_and_purchase_return_item/locale/_messages_doc.json
deleted file mode 100644
index 5129542..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/_messages_doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- "Selling",
- "Description",
- "Sales and Purchase Return Item",
- "Qty",
- "Serial No",
- "Rate",
- "Detail Name",
- "Batch No",
- "Returned Qty",
- "Item Code",
- "UOM"
-]
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/ar-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/ar-doc.json
deleted file mode 100644
index 79de9e8..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/ar-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "\u0644\u0627 \u062f\u0641\u0639\u0629",
- "Description": "\u0648\u0635\u0641",
- "Detail Name": "\u0627\u0644\u0627\u0633\u0645",
- "Item Code": "\u0627\u0644\u0628\u0646\u062f \u0627\u0644\u0631\u0645\u0632",
- "Qty": "\u0627\u0644\u0643\u0645\u064a\u0629",
- "Rate": "\u0645\u0639\u062f\u0644",
- "Returned Qty": "\u0639\u0627\u062f \u0627\u0644\u0643\u0645\u064a\u0629",
- "Sales and Purchase Return Item": "\u0645\u0628\u064a\u0639\u0627\u062a \u0648\u0634\u0631\u0627\u0621 \u0627\u0644\u0633\u0644\u0639\u0629 \u0627\u0644\u0639\u0648\u062f\u0629",
- "Selling": "\u0628\u064a\u0639",
- "Serial No": "\u0627\u0644\u0645\u0633\u0644\u0633\u0644 \u0644\u0627",
- "UOM": "UOM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/de-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/de-doc.json
deleted file mode 100644
index bfcbf4e..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/de-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "Batch No",
- "Description": "Beschreibung",
- "Detail Name": "Detail Name",
- "Item Code": "Item Code",
- "Qty": "Menge",
- "Rate": "Rate",
- "Returned Qty": "Kehrte Menge",
- "Sales and Purchase Return Item": "Sales and Purchase Zur\u00fcck Artikel",
- "Selling": "Verkauf",
- "Serial No": "Serial In",
- "UOM": "UOM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/es-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/es-doc.json
deleted file mode 100644
index 189f5e9..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/es-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "Lote n \u00ba",
- "Description": "Descripci\u00f3n",
- "Detail Name": "Detalle Nombre",
- "Item Code": "C\u00f3digo del art\u00edculo",
- "Qty": "Cantidad",
- "Rate": "Velocidad",
- "Returned Qty": "Cantidad devuelta",
- "Sales and Purchase Return Item": "Venta y Compra de art\u00edculo de vuelta",
- "Selling": "De venta",
- "Serial No": "N\u00famero de orden",
- "UOM": "UOM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/fr-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/fr-doc.json
deleted file mode 100644
index 5064cd7..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/fr-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "Aucun lot",
- "Description": "Description",
- "Detail Name": "Nom de d\u00e9tails",
- "Item Code": "Code de l'article",
- "Qty": "Qt\u00e9",
- "Rate": "Taux",
- "Returned Qty": "Quantit\u00e9 retourn\u00e9e",
- "Sales and Purchase Return Item": "Vente et achat du lot Retour",
- "Selling": "Vente",
- "Serial No": "N \u00b0 de s\u00e9rie",
- "UOM": "Emballage"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/hi-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/hi-doc.json
deleted file mode 100644
index 283b266..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/hi-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "\u0915\u094b\u0908 \u092c\u0948\u091a",
- "Description": "\u0935\u093f\u0935\u0930\u0923",
- "Detail Name": "\u0935\u093f\u0938\u094d\u0924\u093e\u0930 \u0938\u0947 \u0928\u093e\u092e",
- "Item Code": "\u0906\u0907\u091f\u092e \u0915\u094b\u0921",
- "Qty": "\u092e\u093e\u0924\u094d\u0930\u093e",
- "Rate": "\u0926\u0930",
- "Returned Qty": "\u0935\u093e\u092a\u0938 \u0906 \u0917\u090f \u092e\u093e\u0924\u094d\u0930\u093e",
- "Sales and Purchase Return Item": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0914\u0930 \u0916\u0930\u0940\u0926 \u0915\u0947 \u092e\u0926 \u0935\u093e\u092a\u0938\u0940",
- "Selling": "\u0935\u093f\u0915\u094d\u0930\u092f",
- "Serial No": "\u0928\u0939\u0940\u0902 \u0938\u0940\u0930\u093f\u092f\u0932",
- "UOM": "UOM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/hr-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/hr-doc.json
deleted file mode 100644
index 6d5ba06..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/hr-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "Hrpa Ne",
- "Description": "Opis",
- "Detail Name": "Detalj Ime",
- "Item Code": "Stavka \u0160ifra",
- "Qty": "Kol",
- "Rate": "Stopa",
- "Returned Qty": "Vra\u0107eno Kol",
- "Sales and Purchase Return Item": "Prodaja i kupnja Povratak Stavka",
- "Selling": "Prodaja",
- "Serial No": "Serijski br",
- "UOM": "UOM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/nl-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/nl-doc.json
deleted file mode 100644
index 8fe31be..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/nl-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "Batch nr.",
- "Description": "Beschrijving",
- "Detail Name": "Detail Naam",
- "Item Code": "Artikelcode",
- "Qty": "Aantal",
- "Rate": "Tarief",
- "Returned Qty": "Geretourneerde Aantal",
- "Sales and Purchase Return Item": "Verkoop en Inkoop Return Item",
- "Selling": "Selling",
- "Serial No": "Serienummer",
- "UOM": "Verpakking"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/pt-BR-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/pt-BR-doc.json
deleted file mode 100644
index 3cc5b34..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/pt-BR-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "N\u00ba do Lote",
- "Description": "Descri\u00e7\u00e3o",
- "Detail Name": "Nome do Detalhe",
- "Item Code": "C\u00f3digo do Item",
- "Qty": "Qtde.",
- "Rate": "Taxa",
- "Returned Qty": "Qtde. retornada",
- "Sales and Purchase Return Item": "Item de retorno de compra e venda",
- "Selling": "Vendas",
- "Serial No": "N\u00ba de S\u00e9rie",
- "UOM": "UDM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/pt-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/pt-doc.json
deleted file mode 100644
index 56340bc..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/pt-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "No lote",
- "Description": "Descri\u00e7\u00e3o",
- "Detail Name": "Nome detalhes",
- "Item Code": "C\u00f3digo do artigo",
- "Qty": "Qty",
- "Rate": "Taxa",
- "Returned Qty": "Qtde voltou",
- "Sales and Purchase Return Item": "Vendas e item retorno de compra",
- "Selling": "Vendendo",
- "Serial No": "N \u00ba de S\u00e9rie",
- "UOM": "UOM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/sr-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/sr-doc.json
deleted file mode 100644
index e507094..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/sr-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "\u0413\u0440\u0443\u043f\u043d\u043e \u041d\u0435\u043c\u0430",
- "Description": "\u041e\u043f\u0438\u0441",
- "Detail Name": "\u0414\u0435\u0442\u0430\u0459 \u0418\u043c\u0435",
- "Item Code": "\u0428\u0438\u0444\u0440\u0430",
- "Qty": "\u041a\u043e\u043b",
- "Rate": "\u0421\u0442\u043e\u043f\u0430",
- "Returned Qty": "\u0412\u0440\u0430\u045b\u0435\u043d\u0438 \u041a\u043e\u043b",
- "Sales and Purchase Return Item": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0438 \u043a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a \u0430\u0443\u043a\u0446\u0438\u0458\u0438",
- "Selling": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430",
- "Serial No": "\u0421\u0435\u0440\u0438\u0458\u0441\u043a\u0438 \u0431\u0440\u043e\u0458",
- "UOM": "\u0423\u041e\u041c"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/ta-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/ta-doc.json
deleted file mode 100644
index c60a081..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/ta-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "\u0ba4\u0bc6\u0bbe\u0b95\u0bc1\u0ba4\u0bbf \u0b87\u0bb2\u0bcd\u0bb2\u0bc8",
- "Description": "\u0bb5\u0bbf\u0bb3\u0b95\u0bcd\u0b95\u0bae\u0bcd",
- "Detail Name": "\u0bb5\u0bbf\u0bb0\u0bbf\u0bb5\u0bbe\u0b95 \u0baa\u0bc6\u0baf\u0bb0\u0bcd",
- "Item Code": "\u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf\u0baf\u0bc8 \u0b95\u0bc7\u0bbe\u0b9f\u0bcd",
- "Qty": "\u0b85\u0bb3\u0bb5\u0bc1",
- "Rate": "\u0bb5\u0bbf\u0bb2\u0bc8",
- "Returned Qty": "\u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bbf \u0b85\u0bb3\u0bb5\u0bc1",
- "Sales and Purchase Return Item": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b95\u0bc6\u0bbe\u0bb3\u0bcd\u0bae\u0bc1\u0ba4\u0bb2\u0bcd \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf",
- "Selling": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8",
- "Serial No": "\u0b87\u0bb2\u0bcd\u0bb2\u0bc8 \u0ba4\u0bc6\u0bbe\u0b9f\u0bb0\u0bcd",
- "UOM": "\u0bae\u0bc6\u0bbe\u0bb1\u0b9f\u0bcd\u0b9f\u0bc1\u0bb5 \u0baa\u0bb2\u0bcd\u0b95\u0bb2\u0bc8\u0b95\u0bb4\u0b95\u0bae\u0bcd"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/locale/th-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/th-doc.json
deleted file mode 100644
index b47f740..0000000
--- a/selling/doctype/sales_and_purchase_return_item/locale/th-doc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "Batch No": "\u0e0a\u0e38\u0e14\u0e44\u0e21\u0e48\u0e21\u0e35",
- "Description": "\u0e25\u0e31\u0e01\u0e29\u0e13\u0e30",
- "Detail Name": "\u0e0a\u0e37\u0e48\u0e2d\u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14",
- "Item Code": "\u0e23\u0e2b\u0e31\u0e2a\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32",
- "Qty": "\u0e08\u0e33\u0e19\u0e27\u0e19",
- "Rate": "\u0e2d\u0e31\u0e15\u0e23\u0e32",
- "Returned Qty": "\u0e08\u0e33\u0e19\u0e27\u0e19\u0e01\u0e25\u0e31\u0e1a",
- "Sales and Purchase Return Item": "\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\u0e01\u0e25\u0e31\u0e1a",
- "Selling": "\u0e02\u0e32\u0e22",
- "Serial No": "\u0e2d\u0e19\u0e38\u0e01\u0e23\u0e21\u0e44\u0e21\u0e48\u0e21\u0e35",
- "UOM": "UOM"
-}
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.py b/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.py
deleted file mode 100644
index 7f48feb..0000000
--- a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-import webnotes
-
-class DocType:
- def __init__(self, d, dl):
- self.doc, self.doclist = d, dl
\ No newline at end of file
diff --git a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.txt b/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.txt
deleted file mode 100644
index 179a6a3..0000000
--- a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-[
- {
- "creation": "2013-01-10 16:34:20",
- "docstatus": 0,
- "modified": "2013-01-29 16:27:54",
- "modified_by": "Administrator",
- "owner": "wasim@webnotestech.com"
- },
- {
- "doctype": "DocType",
- "istable": 1,
- "module": "Selling",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Sales and Purchase Return Item",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "doctype": "DocType",
- "name": "Sales and Purchase Return Item"
- },
- {
- "doctype": "DocField",
- "fieldname": "item_code",
- "fieldtype": "Link",
- "label": "Item Code",
- "oldfieldname": "item_code",
- "oldfieldtype": "Link",
- "options": "Item",
- "read_only": 1,
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "description",
- "fieldtype": "Data",
- "label": "Description",
- "oldfieldname": "description",
- "oldfieldtype": "Data",
- "read_only": 1,
- "width": "300px"
- },
- {
- "doctype": "DocField",
- "fieldname": "uom",
- "fieldtype": "Link",
- "label": "UOM",
- "oldfieldname": "uom",
- "oldfieldtype": "Link",
- "options": "UOM",
- "read_only": 1,
- "search_index": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "rate",
- "fieldtype": "Currency",
- "label": "Rate",
- "oldfieldname": "rate",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "qty",
- "fieldtype": "Data",
- "label": "Qty",
- "oldfieldname": "qty",
- "oldfieldtype": "Data",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "returned_qty",
- "fieldtype": "Data",
- "label": "Returned Qty",
- "oldfieldname": "returned_qty",
- "oldfieldtype": "Data",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "serial_no",
- "fieldtype": "Small Text",
- "label": "Serial No"
- },
- {
- "doctype": "DocField",
- "fieldname": "batch_no",
- "fieldtype": "Data",
- "label": "Batch No"
- },
- {
- "doctype": "DocField",
- "fieldname": "detail_name",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Detail Name",
- "oldfieldname": "detail_name",
- "oldfieldtype": "Data",
- "read_only": 1
- }
-]
\ No newline at end of file
diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py
index 47d139f..12ae4a8 100644
--- a/selling/doctype/sales_common/sales_common.py
+++ b/selling/doctype/sales_common/sales_common.py
@@ -341,12 +341,10 @@
# ========================================================================
# it indicates % contribution of sales person in sales
def get_allocated_sum(self,obj):
- sum = 0
- for d in getlist(obj.doclist,'sales_team'):
- sum += flt(d.allocated_percentage)
- if (flt(sum) != 100) and getlist(obj.doclist,'sales_team'):
- msgprint("Total Allocated % of Sales Persons should be 100%")
- raise Exception
+ sales_team_list = obj.doclist.get({"parentfield": "sales_team"})
+ total_allocation = sum([flt(d.allocated_percentage) for d in sales_team_list])
+ if sales_team_list and total_allocation != 100.0:
+ msgprint("Total Allocated %% of Sales Persons should be 100%", raise_exception=True)
# Check Conversion Rate (i.e. it will not allow conversion rate to be 1 for Currency other than default currency set in Global Defaults)
# ===========================================================================
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index 8205afb..5009c4e 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -156,9 +156,13 @@
f = [d.item_code, d.description]
#check item is stock item
- st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
+ st_itm = sql("select is_stock_item from `tabItem` where name = %s", d.item_code)
if st_itm and st_itm[0][0] == 'Yes':
+ if not d.reserved_warehouse:
+ msgprint("""Please enter Reserved Warehouse for item %s
+ as it is stock Item""" % d.item_code, raise_exception=1)
+
if e in check_list:
msgprint("Item %s has been entered twice." % d.item_code)
else:
@@ -333,10 +337,6 @@
def update_stock_ledger(self, update_stock, is_stopped = 0):
for d in self.get_item_list(is_stopped):
if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
- if not d['reserved_warehouse']:
- msgprint("""Please enter Reserved Warehouse for item %s
- as it is stock Item""" % d['item_code'], raise_exception=1)
-
args = {
"item_code": d['item_code'],
"reserved_qty": flt(update_stock) * flt(d['reserved_qty']),
diff --git a/selling/doctype/sales_order/test_sales_order.py b/selling/doctype/sales_order/test_sales_order.py
index 5d820fe..40a10b4 100644
--- a/selling/doctype/sales_order/test_sales_order.py
+++ b/selling/doctype/sales_order/test_sales_order.py
@@ -65,7 +65,7 @@
# submit dn
dn = self.create_dn_against_so(so)
- self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 6.0)
+ self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 5.0)
# stop so
so.load_from_db()
@@ -75,7 +75,7 @@
# unstop so
so.load_from_db()
so.obj.unstop_sales_order()
- self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 6.0)
+ self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 5.0)
# cancel dn
dn.cancel()
@@ -151,9 +151,9 @@
dn = self.create_dn_against_so(so)
self.check_reserved_qty(sbom_test_records[0][1]["item_code"],
- so.doclist[1].reserved_warehouse, 30.0)
+ so.doclist[1].reserved_warehouse, 25.0)
self.check_reserved_qty(sbom_test_records[0][2]["item_code"],
- so.doclist[1].reserved_warehouse, 12.0)
+ so.doclist[1].reserved_warehouse, 10.0)
# stop so
so.load_from_db()
@@ -168,9 +168,9 @@
so.load_from_db()
so.obj.unstop_sales_order()
self.check_reserved_qty(sbom_test_records[0][1]["item_code"],
- so.doclist[1].reserved_warehouse, 30.0)
+ so.doclist[1].reserved_warehouse, 25.0)
self.check_reserved_qty(sbom_test_records[0][2]["item_code"],
- so.doclist[1].reserved_warehouse, 12.0)
+ so.doclist[1].reserved_warehouse, 10.0)
# cancel dn
dn.cancel()
@@ -234,8 +234,8 @@
"price_list_name": "_Test Price List",
"territory": "_Test Territory",
"transaction_date": "2013-02-21",
- "grand_total": 500.0,
- "grand_total_export": 500.0,
+ "grand_total": 1000.0,
+ "grand_total_export": 1000.0,
},
{
"description": "CPU",
@@ -244,9 +244,9 @@
"item_name": "CPU",
"parentfield": "sales_order_details",
"qty": 10.0,
- "basic_rate": 50.0,
- "export_rate": 50.0,
- "amount": 500.0,
+ "basic_rate": 100.0,
+ "export_rate": 100.0,
+ "amount": 1000.0,
"reserved_warehouse": "_Test Warehouse",
}
],
diff --git a/selling/doctype/sales_order_item/sales_order_item.txt b/selling/doctype/sales_order_item/sales_order_item.txt
index dc8d19e..fff2d08 100644
--- a/selling/doctype/sales_order_item/sales_order_item.txt
+++ b/selling/doctype/sales_order_item/sales_order_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:21",
+ "creation": "2013-02-22 01:27:52",
"docstatus": 0,
- "modified": "2013-01-29 16:27:54",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -34,6 +34,7 @@
"oldfieldname": "item_code",
"oldfieldtype": "Link",
"options": "Item",
+ "print_width": "150px",
"reqd": 1,
"search_index": 1,
"width": "150px"
@@ -55,6 +56,7 @@
"oldfieldname": "item_name",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150",
"reqd": 1,
"width": "150"
},
@@ -66,6 +68,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Small Text",
+ "print_width": "300px",
"reqd": 1,
"search_index": 1,
"width": "300px"
@@ -78,6 +81,7 @@
"label": "Quantity",
"oldfieldname": "qty",
"oldfieldtype": "Currency",
+ "print_width": "100px",
"reqd": 1,
"width": "100px"
},
@@ -89,6 +93,7 @@
"label": "UOM",
"oldfieldname": "stock_uom",
"oldfieldtype": "Data",
+ "print_width": "70px",
"read_only": 1,
"reqd": 0,
"width": "70px"
@@ -103,6 +108,7 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 1,
+ "print_width": "70px",
"reqd": 0,
"width": "70px"
},
@@ -115,6 +121,7 @@
"oldfieldname": "adj_rate",
"oldfieldtype": "Float",
"print_hide": 1,
+ "print_width": "70px",
"width": "70px"
},
{
@@ -126,6 +133,7 @@
"oldfieldname": "export_rate",
"oldfieldtype": "Currency",
"options": "currency",
+ "print_width": "100px",
"reqd": 0,
"width": "100px"
},
@@ -139,6 +147,7 @@
"oldfieldname": "export_amount",
"oldfieldtype": "Currency",
"options": "currency",
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"width": "100px"
@@ -152,6 +161,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -165,6 +175,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"reqd": 0,
"width": "100px"
},
@@ -179,6 +190,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"width": "100px"
@@ -193,6 +205,7 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"print_hide": 1,
+ "print_width": "150px",
"reqd": 0,
"width": "150px"
},
@@ -207,6 +220,7 @@
"oldfieldname": "projected_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "70px",
"read_only": 1,
"width": "70px"
},
@@ -218,6 +232,7 @@
"label": "Actual Qty",
"no_copy": 1,
"print_hide": 1,
+ "print_width": "70px",
"read_only": 1,
"width": "70px"
},
@@ -233,6 +248,7 @@
"oldfieldname": "delivered_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"search_index": 0,
"width": "100px"
@@ -258,6 +274,7 @@
"oldfieldname": "planned_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "50px",
"read_only": 1,
"report_hide": 1,
"width": "50px"
@@ -272,6 +289,7 @@
"oldfieldname": "produced_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "50px",
"read_only": 1,
"report_hide": 1,
"width": "50px"
diff --git a/selling/doctype/sales_team/sales_team.txt b/selling/doctype/sales_team/sales_team.txt
index c1a00d7..add466c 100644
--- a/selling/doctype/sales_team/sales_team.txt
+++ b/selling/doctype/sales_team/sales_team.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:22",
+ "creation": "2013-02-22 01:27:53",
"docstatus": 0,
- "modified": "2013-01-29 16:27:56",
+ "modified": "2013-03-07 07:03:31",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -33,6 +33,7 @@
"oldfieldname": "sales_person",
"oldfieldtype": "Link",
"options": "Sales Person",
+ "print_width": "200px",
"reqd": 1,
"search_index": 1,
"width": "200px"
@@ -44,6 +45,7 @@
"label": "Designation",
"oldfieldname": "sales_designation",
"oldfieldtype": "Data",
+ "print_width": "100px",
"width": "100px"
},
{
@@ -54,6 +56,7 @@
"label": "Contact No.",
"oldfieldname": "contact_no",
"oldfieldtype": "Data",
+ "print_width": "100px",
"width": "100px"
},
{
@@ -63,6 +66,7 @@
"label": "Allocated (%)",
"oldfieldname": "allocated_percentage",
"oldfieldtype": "Currency",
+ "print_width": "100px",
"reqd": 0,
"width": "100px"
},
@@ -74,6 +78,7 @@
"oldfieldname": "allocated_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
+ "print_width": "120px",
"reqd": 0,
"width": "120px"
},
diff --git a/selling/page/sales_analytics/sales_analytics.js b/selling/page/sales_analytics/sales_analytics.js
index 499c6c0..0b35af5 100644
--- a/selling/page/sales_analytics/sales_analytics.js
+++ b/selling/page/sales_analytics/sales_analytics.js
@@ -122,18 +122,8 @@
setup_filters: function() {
var me = this;
this._super();
-
- this.filter_inputs.value_or_qty.change(function() {
- me.filter_inputs.refresh.click();
- });
-
- this.filter_inputs.tree_type.change(function() {
- me.filter_inputs.refresh.click();
- });
- this.filter_inputs.based_on.change(function() {
- me.filter_inputs.refresh.click();
- });
+ this.trigger_refresh_on_change(["value_or_qty", "tree_type", "based_on"]);
this.show_zero_check()
this.setup_plot_check();
diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js
index 7af9b71..994bb4a 100644
--- a/selling/page/selling_home/selling_home.js
+++ b/selling/page/selling_home/selling_home.js
@@ -121,12 +121,6 @@
icon: "icon-wrench",
items: [
{
- "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool",
- "label":wn._("Sales Returns"),
- "description":wn._("Helper for managing return of goods (sales or purchase)"),
- doctype: "Sales and Purchase Return Tool"
- },
- {
"route":"Form/SMS Center/SMS Center",
"label":wn._("SMS Center"),
"description":wn._("Send mass SMS to your contacts"),
diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py
new file mode 100644
index 0000000..2c7fda6
--- /dev/null
+++ b/setup/doctype/backup_manager/backup_dropbox.py
@@ -0,0 +1,122 @@
+# SETUP:
+# install pip install --upgrade dropbox
+#
+# Create new Dropbox App
+#
+# in conf.py, set oauth2 settings
+# dropbox_access_key
+# dropbox_access_secret
+
+
+import os
+import webnotes
+from webnotes.utils import get_request_site_address, get_base_path
+from webnotes import _
+
+@webnotes.whitelist()
+def get_dropbox_authorize_url():
+ sess = get_dropbox_session()
+ request_token = sess.obtain_request_token()
+ return_address = get_request_site_address(True) \
+ + "?cmd=setup.doctype.backup_manager.backup_dropbox.dropbox_callback"
+
+ url = sess.build_authorize_url(request_token, return_address)
+
+ return {
+ "url": url,
+ "key": request_token.key,
+ "secret": request_token.secret,
+ }
+
+@webnotes.whitelist(allow_guest=True)
+def dropbox_callback(oauth_token=None, not_approved=False):
+ from dropbox import client
+ if not not_approved:
+ if webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token:
+ allowed = 1
+ message = "Dropbox access allowed."
+
+ sess = get_dropbox_session()
+ sess.set_request_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"),
+ webnotes.conn.get_value("Backup Manager", None, "dropbox_access_secret"))
+ access_token = sess.obtain_access_token()
+ webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_key", access_token.key)
+ webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret", access_token.secret)
+ webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", allowed)
+ dropbox_client = client.DropboxClient(sess)
+ dropbox_client.file_create_folder("files")
+
+ else:
+ allowed = 0
+ message = "Illegal Access Token Please try again."
+ else:
+ allowed = 0
+ message = "Dropbox Access not approved."
+
+ webnotes.message_title = "Dropbox Approval"
+ webnotes.message = "<h3>%s</h3><p>Please close this window.</p>" % message
+
+ webnotes.conn.commit()
+ webnotes.response['type'] = 'page'
+ webnotes.response['page_name'] = 'message.html'
+
+def backup_to_dropbox():
+ from dropbox import client, session, rest
+ from conf import dropbox_access_key, dropbox_secret_key
+ from webnotes.utils.backups import new_backup
+ if not webnotes.conn:
+ webnotes.connect()
+
+ sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder")
+
+ sess.set_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"),
+ webnotes.conn.get_value("Backup Manager", None, "dropbox_access_secret"))
+
+ dropbox_client = client.DropboxClient(sess)
+
+ # upload database
+ backup = new_backup()
+ filename = os.path.join(get_base_path(), "public", "backups",
+ os.path.basename(backup.backup_path_db))
+ upload_file_to_dropbox(filename, "database", dropbox_client)
+
+ response = dropbox_client.metadata("/files")
+
+ # upload files to files folder
+ filename = os.path.join(get_base_path(), "public", "files")
+ for filename in os.listdir(filename):
+ found = False
+ for file_metadata in response["contents"]:
+ if filename==os.path.basename(file_metadata["path"]):
+ if os.stat(filename).st_size==file_metadata["bytes"]:
+ found=True
+
+ if not found:
+ upload_file_to_dropbox(os.path.join(get_base_path(),"public", "files", filename), "files", dropbox_client)
+
+def get_dropbox_session():
+ from dropbox import session
+ try:
+ from conf import dropbox_access_key, dropbox_secret_key
+ except ImportError, e:
+ webnotes.msgprint(_("Please set Dropbox access keys in") + " conf.py",
+ raise_exception=True)
+ sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder")
+ return sess
+
+def upload_file_to_dropbox(filename, folder, dropbox_client):
+ size = os.stat(filename).st_size
+ f = open(filename,'r')
+ if size > 4194304:
+ uploader = dropbox_client.get_chunked_uploader(f, size)
+ while uploader.offset < size:
+ try:
+ uploader.upload_chunked()
+ finish(folder + '/' + os.path.basename(filename), overwrite='True')
+ except rest.ErrorResponse, e:
+ pass
+ else:
+ response = dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True)
+
+if __name__=="__main__":
+ backup_to_dropbox()
\ No newline at end of file
diff --git a/setup/doctype/backup_manager/backup_googledrive.py b/setup/doctype/backup_manager/backup_googledrive.py
new file mode 100644
index 0000000..c794672
--- /dev/null
+++ b/setup/doctype/backup_manager/backup_googledrive.py
@@ -0,0 +1,161 @@
+# SETUP:
+# install pip install --upgrade google-api-python-client
+#
+# In Google API
+# - create new API project
+# - create new oauth2 client (create installed app type as google \
+# does not support subdomains)
+#
+# in conf.py, set oauth2 settings
+# gdrive_client_id
+# gdrive_client_secret
+
+import httplib2
+import sys
+import os
+import mimetypes
+import webnotes
+import oauth2client.client
+from webnotes.utils import get_request_site_address, get_base_path
+from webnotes import _, msgprint
+from apiclient.discovery import build
+from apiclient.http import MediaFileUpload
+
+@webnotes.whitelist()
+def get_gdrive_authorize_url():
+ flow = get_gdrive_flow()
+ authorize_url = flow.step1_get_authorize_url()
+ return {
+ "authorize_url": authorize_url,
+ }
+
+@webnotes.whitelist()
+def upload_files(name, mimetype, service, folder_id):
+ if not webnotes.conn:
+ webnotes.connect()
+ file_name = os.path.basename(name)
+ media_body = MediaFileUpload(name, mimetype=mimetype, resumable=True)
+ body = {
+ 'title': file_name,
+ 'description': 'Backup File',
+ 'mimetype': mimetype,
+ 'parents': [{
+ 'kind': 'drive#filelink',
+ 'id': folder_id
+ }]
+ }
+ request = service.files().insert(body=body, media_body=media_body)
+ response = None
+ while response is None:
+ status, response = request.next_chunk()
+
+def backup_to_gdrive():
+ from webnotes.utils.backups import new_backup
+ found_database = False
+ found_files = False
+ if not webnotes.conn:
+ webnotes.connect()
+ flow = get_gdrive_flow()
+ credentials_json = webnotes.conn.get_value("Backup Manager", None, "gdrive_credentials")
+ credentials = oauth2client.client.Credentials.new_from_json(credentials_json)
+ http = httplib2.Http()
+ http = credentials.authorize(http)
+ drive_service = build('drive', 'v2', http=http)
+
+ # upload database
+ backup = new_backup()
+ path = os.path.join(get_base_path(), "public", "backups")
+ filename = os.path.join(path, os.path.basename(backup.backup_path_db))
+
+ # upload files to database folder
+ upload_files(filename, 'application/x-gzip', drive_service,
+ webnotes.conn.get_value("Backup Manager", None, "database_folder_id"))
+
+ # upload files to files folder
+ path = os.path.join(get_base_path(), "public", "files")
+ for files in os.listdir(path):
+ filename = path + "/" + files
+ ext = filename.split('.')[-1]
+ size = os.path.getsize(filename)
+ if ext == 'gz' or ext == 'gzip':
+ mimetype = 'application/x-gzip'
+ else:
+ mimetype = mimetypes.types_map["." + ext]
+ #Compare Local File with Server File
+ param = {}
+ children = drive_service.children().list(
+ folderId=webnotes.conn.get_value("Backup Manager", None, "files_folder_id"),
+ **param).execute()
+ for child in children.get('items', []):
+ file = drive_service.files().get(fileId=child['id']).execute()
+ if files == file['title'] and size == int(file['fileSize']):
+ found_files = True
+ break
+ if not found_files:
+ upload_files(filename, mimetype, drive_service, webnotes.conn.get_value("Backup Manager", None, "files_folder_id"))
+
+def get_gdrive_flow():
+ from oauth2client.client import OAuth2WebServerFlow
+ import conf
+
+ if not hasattr(conf, "gdrive_client_id"):
+ webnotes.msgprint(_("Please set Google Drive access keys in") + " conf.py",
+ raise_exception=True)
+
+ #callback_url = get_request_site_address(True) \
+ # + "?cmd=setup.doctype.backup_manager.backup_googledrive.googledrive_callback"
+
+ # for installed apps since google does not support subdomains
+ redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
+
+ flow = OAuth2WebServerFlow(conf.gdrive_client_id, conf.gdrive_client_secret,
+ "https://www.googleapis.com/auth/drive", redirect_uri)
+ return flow
+
+@webnotes.whitelist()
+def gdrive_callback(verification_code = None):
+ flow = get_gdrive_flow()
+ if verification_code:
+ credentials = flow.step2_exchange(verification_code)
+ allowed = 1
+
+ # make folders to save id
+ http = httplib2.Http()
+ http = credentials.authorize(http)
+ drive_service = build('drive', 'v2', http=http)
+ erpnext_folder_id = create_erpnext_folder(drive_service)
+ database_folder_id = create_folder('database', drive_service, erpnext_folder_id)
+ files_folder_id = create_folder('files', drive_service, erpnext_folder_id)
+
+ webnotes.conn.set_value("Backup Manager", "Backup Manager", "gdrive_access_allowed", allowed)
+ webnotes.conn.set_value("Backup Manager", "Backup Manager", "database_folder_id", database_folder_id)
+ webnotes.conn.set_value("Backup Manager", "Backup Manager", "files_folder_id", files_folder_id)
+ final_credentials = credentials.to_json()
+ webnotes.conn.set_value("Backup Manager", "Backup Manager", "gdrive_credentials", final_credentials)
+
+ webnotes.msgprint("Updated")
+
+def create_erpnext_folder(service):
+ if not webnotes.conn:
+ webnotes.connect()
+ erpnext = {
+ 'title': 'erpnext',
+ 'mimeType': 'application/vnd.google-apps.folder'
+ }
+ erpnext = service.files().insert(body=erpnext).execute()
+ return erpnext['id']
+
+def create_folder(name, service, folder_id):
+ database = {
+ 'title': name,
+ 'mimeType': 'application/vnd.google-apps.folder',
+ 'parents': [{
+ 'kind': 'drive#fileLink',
+ 'id': folder_id
+ }]
+ }
+ database = service.files().insert(body=database).execute()
+ return database['id']
+
+if __name__=="__main__":
+ backup_to_gdrive()
\ No newline at end of file
diff --git a/setup/doctype/backup_manager/backup_manager.js b/setup/doctype/backup_manager/backup_manager.js
index a0f7f71..28315c5 100644
--- a/setup/doctype/backup_manager/backup_manager.js
+++ b/setup/doctype/backup_manager/backup_manager.js
@@ -1,14 +1,65 @@
+cur_frm.cscript.refresh = function(doc) {
+ cur_frm.disable_save();
+}
+
+//dropbox
cur_frm.cscript.allow_dropbox_access = function(doc) {
- wn.call({
- method: "setup.doctype.backup_manager.backup_manager.get_dropbox_authorize_url",
- callback: function(r) {
- if(!r.exc) {
- cur_frm.set_value("dropbox_access_secret", r.message.secret);
- cur_frm.set_value("dropbox_access_key", r.message.key);
- cur_frm.save(null, function() {
- window.open(r.message.url);
- });
+ if (doc.send_notifications_to == '') {
+ msgprint("Please enter email address.")
+ }
+ else {
+ wn.call({
+ method: "setup.doctype.backup_manager.backup_dropbox.get_dropbox_authorize_url",
+ callback: function(r) {
+ if(!r.exc) {
+ cur_frm.set_value("dropbox_access_secret", r.message.secret);
+ cur_frm.set_value("dropbox_access_key", r.message.key);
+ cur_frm.save(null, function() {
+ window.open(r.message.url);
+ });
+ }
}
+ })
+ }
+}
+
+cur_frm.cscript.backup_right_now = function(doc) {
+ msgprint("Backing up and uploading. This may take a few minutes.")
+ wn.call({
+ method: "setup.doctype.backup_manager.backup_manager.take_backups_dropbox",
+ callback: function(r) {
+ msgprint("Backups taken. Please check your email for the response.")
}
})
-}
\ No newline at end of file
+}
+//gdrive
+cur_frm.cscript.allow_gdrive_access = function(doc) {
+ if (doc.send_notifications_to == '') {
+ msgprint("Please enter email address.")
+ }
+ else {
+ wn.call({
+ method: "setup.doctype.backup_manager.backup_googledrive.get_gdrive_authorize_url",
+ callback: function(r) {
+ window.open(r.message.authorize_url);
+ }
+ })
+ }
+}
+
+cur_frm.cscript.validate_gdrive = function(doc) {
+ wn.call({
+ method: "setup.doctype.backup_manager.backup_manager.gdrive_callback",
+ args: {
+ verification_code: doc.verification_code
+ },
+ });
+}
+
+cur_frm.cscript.upload_backups_to_dropbox = function(doc) {
+ cur_frm.save()
+}
+
+cur_frm.cscript.upload_backups_to_gdrive = function(doc) {
+ cur_frm.save()
+}
diff --git a/setup/doctype/backup_manager/backup_manager.py b/setup/doctype/backup_manager/backup_manager.py
index fc41654..213aa85 100644
--- a/setup/doctype/backup_manager/backup_manager.py
+++ b/setup/doctype/backup_manager/backup_manager.py
@@ -3,51 +3,61 @@
from __future__ import unicode_literals
import webnotes
from webnotes import _
-from webnotes.utils import get_request_site_address
+from backup_dropbox import dropbox_callback, get_dropbox_session, get_dropbox_authorize_url
+from backup_googledrive import gdrive_callback, get_gdrive_flow, get_gdrive_authorize_url
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
-@webnotes.whitelist()
-def get_dropbox_authorize_url():
- from dropbox import session
+def take_backups_daily():
+ take_backups_if("Daily")
+def take_backups_weekly():
+ take_backups_if("Weekly")
+
+def take_backups_if(freq):
+ if webnotes.conn.get_value("Backup Manager", None, "upload_backups_to_dropbox")==freq:
+ take_backups_dropbox()
+
+ if webnotes.conn.get_value("Backup Manager", None, "upload_backups_to_gdrive")==freq:
+ take_backups_gdrive()
+
+@webnotes.whitelist()
+def take_backups_dropbox():
try:
- from conf import dropbox_access_key, dropbox_secret_key
- except ImportError, e:
- webnotes.msgprint(_("Please set Dropbox access keys in") + " conf.py",
- raise_exception=True)
-
- sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder")
- request_token = sess.obtain_request_token()
- return_address = get_request_site_address(True) \
- + "?cmd=setup.doctype.backup_manager.backup_manager.dropbox_callback"
-
- url = sess.build_authorize_url(request_token, return_address)
-
- return {
- "url": url,
- "key": request_token.key,
- "secret": request_token.secret,
- }
-
-@webnotes.whitelist(allow_guest=True)
-def dropbox_callback(oauth_token=None, not_approved=False):
- if not not_approved:
- if webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token:
- webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 1)
- message = "Dropbox access allowed."
- else:
- webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0)
- message = "Illegal Access Token Please try again."
+ from setup.doctype.backup_manager.backup_dropbox import backup_to_dropbox
+ backup_to_dropbox()
+ send_email(True, "Dropbox")
+ except Exception, e:
+ send_email(False, "Dropbox", e)
+
+#backup to gdrive
+@webnotes.whitelist()
+def take_backups_gdrive():
+ try:
+ from setup.doctype.backup_manager.backup_googledrive import backup_to_gdrive
+ backup_to_gdrive()
+ send_email(True, "Google Drive")
+ except Exception, e:
+ send_email(False, "Google Drive", e)
+
+def send_email(success, service_name, error_status=None):
+ if success:
+ subject = "Backup Upload Successful"
+ message ="""<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you
+ that your backup was successfully uploaded to your %s account. So relax!</p>
+ """ % service_name
+
else:
- webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0)
- message = "Dropbox Access not approved."
+ subject = "[Warning] Backup Upload Failed"
+ message ="""<h3>Backup Upload Failed</h3><p>Oops, your automated backup to %s
+ failed.</p>
+ <p>Error message: %s</p>
+ <p>Please contact your system manager for more information.</p>
+ """ % (service_name, error_status)
- webnotes.message_title = "Dropbox Approval"
- webnotes.message = "<h3>%s</h3><p>Please close this window.</p>" % message
-
- webnotes.conn.commit()
- webnotes.response['type'] = 'page'
- webnotes.response['page_name'] = 'message.html'
+ # email system managers
+ from webnotes.utils.email_lib import sendmail
+ sendmail(webnotes.conn.get_value("Backup Manager", None, "send_notifications_to").split(","),
+ subject=subject, msg=message)
\ No newline at end of file
diff --git a/setup/doctype/backup_manager/backup_manager.txt b/setup/doctype/backup_manager/backup_manager.txt
index bf5d686..9a43f34 100644
--- a/setup/doctype/backup_manager/backup_manager.txt
+++ b/setup/doctype/backup_manager/backup_manager.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-03-05 16:35:50",
+ "creation": "2013-03-15 11:06:59",
"docstatus": 0,
- "modified": "2013-03-05 18:05:05",
+ "modified": "2013-03-15 17:27:33",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -40,6 +40,29 @@
},
{
"doctype": "DocField",
+ "fieldname": "setup",
+ "fieldtype": "Section Break",
+ "label": "Setup"
+ },
+ {
+ "description": "Email ids separated by commas.",
+ "doctype": "DocField",
+ "fieldname": "send_notifications_to",
+ "fieldtype": "Data",
+ "label": "Send Notifications To",
+ "reqd": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "backup_right_now",
+ "fieldtype": "Button",
+ "hidden": 1,
+ "label": "Backup Right Now",
+ "read_only": 1
+ },
+ {
+ "description": "Note: Backups and files are not deleted from Dropbox, you will have to delete them manually.",
+ "doctype": "DocField",
"fieldname": "sync_with_dropbox",
"fieldtype": "Section Break",
"label": "Sync with Dropbox"
@@ -47,27 +70,31 @@
{
"doctype": "DocField",
"fieldname": "upload_backups_to_dropbox",
- "fieldtype": "Check",
- "label": "Upload Backups to Dropbox"
+ "fieldtype": "Select",
+ "label": "Upload Backups to Dropbox",
+ "options": "Never\nWeekly\nDaily"
},
{
"doctype": "DocField",
"fieldname": "dropbox_access_key",
"fieldtype": "Data",
"hidden": 1,
- "label": "Dropbox Access Key"
+ "label": "Dropbox Access Key",
+ "read_only": 1
},
{
"doctype": "DocField",
"fieldname": "dropbox_access_secret",
"fieldtype": "Data",
"hidden": 1,
- "label": "Dropbox Access Secret"
+ "label": "Dropbox Access Secret",
+ "read_only": 1
},
{
"doctype": "DocField",
"fieldname": "dropbox_access_allowed",
"fieldtype": "Check",
+ "hidden": 1,
"label": "Dropbox Access Allowed",
"read_only": 1
},
@@ -78,6 +105,70 @@
"label": "Allow Dropbox Access"
},
{
+ "description": "Note: Backups and files are not deleted from Google Drive, you will have to delete them manually.",
+ "doctype": "DocField",
+ "fieldname": "sync_with_gdrive",
+ "fieldtype": "Section Break",
+ "label": "Sync with Google Drive"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "upload_backups_to_gdrive",
+ "fieldtype": "Select",
+ "label": "Upload Backups to Google Drive",
+ "options": "Never\nDaily\nWeekly"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "allow_gdrive_access",
+ "fieldtype": "Button",
+ "label": "Allow Google Drive Access"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "verification_code",
+ "fieldtype": "Data",
+ "label": "Enter Verification Code"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "validate_gdrive",
+ "fieldtype": "Button",
+ "label": "Validate"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "gdrive_access_allowed",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Google Drive Access Allowed",
+ "read_only": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "gdrive_credentials",
+ "fieldtype": "Text",
+ "hidden": 1,
+ "label": "Credentials",
+ "read_only": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "database_folder_id",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Database Folder ID",
+ "read_only": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "files_folder_id",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Files Folder ID",
+ "read_only": 1
+ },
+ {
"doctype": "DocPerm"
}
]
\ No newline at end of file
diff --git a/setup/doctype/company/company.js b/setup/doctype/company/company.js
index a84bbc9..a898823 100644
--- a/setup/doctype/company/company.js
+++ b/setup/doctype/company/company.js
@@ -58,3 +58,43 @@
cur_frm.fields_dict.payables_group.get_query = function(doc) {
return 'SELECT `tabAccount`.name FROM `tabAccount` WHERE `tabAccount`.company = "'+doc.name+'" AND `tabAccount`.group_or_ledger = "Group" AND `tabAccount`.docstatus != 2 AND `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.name LIMIT 50';
}
+
+
+cur_frm.fields_dict["stock_in_hand_account"].get_query = function(doc) {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": {
+ "is_pl_account": "No",
+ "debit_or_credit": "Debit",
+ "company": doc.name
+ }
+ }
+}
+
+cur_frm.fields_dict["stock_adjustment_account"].get_query = function(doc) {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": {
+ "is_pl_account": "Yes",
+ "debit_or_credit": "Debit",
+ "company": doc.name
+ }
+ }
+}
+
+cur_frm.fields_dict["expenses_included_in_valuation"].get_query =
+ cur_frm.fields_dict["stock_adjustment_account"].get_query;
+
+cur_frm.fields_dict["stock_delivered_but_not_billed"].get_query =
+ cur_frm.fields_dict["stock_in_hand_account"].get_query;
+
+cur_frm.fields_dict["stock_received_but_not_billed"].get_query = function(doc) {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": {
+ "is_pl_account": "No",
+ "debit_or_credit": "Credit",
+ "company": doc.name
+ }
+ }
+}
\ No newline at end of file
diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py
index 9cf722f..15241a2 100644
--- a/setup/doctype/company/company.py
+++ b/setup/doctype/company/company.py
@@ -17,7 +17,7 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import cstr, set_default
+from webnotes.utils import cstr
from webnotes.model.doc import Document
from webnotes.model.code import get_obj
import webnotes.defaults
@@ -47,10 +47,11 @@
['Loans and Advances (Assets)','Current Assets','Group','No','','Debit',self.doc.name,''],
['Securities and Deposits','Current Assets','Group','No','','Debit',self.doc.name,''],
['Earnest Money','Securities and Deposits','Ledger','No','','Debit',self.doc.name,''],
- ['Stock In Hand','Current Assets','Group','No','','Debit',self.doc.name,''],
- ['Stock','Stock In Hand','Ledger','No','','Debit',self.doc.name,''],
+ ['Stock Assets','Current Assets','Group','No','','Debit',self.doc.name,''],
+ ['Stock In Hand','Stock Assets','Ledger','No','','Debit',self.doc.name,''],
+ ['Stock Delivered But Not Billed', 'Stock Assets', 'Ledger',
+ 'No', '', 'Debit', self.doc.name, ''],
['Tax Assets','Current Assets','Group','No','','Debit',self.doc.name,''],
- ['Stock Delivered But Not Billed','Current Assets','Ledger','No','','Debit',self.doc.name,''],
['Fixed Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''],
['Capital Equipments','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''],
['Computers','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''],
@@ -62,9 +63,10 @@
['Temporary Account (Assets)','Temporary Accounts (Assets)','Ledger','No','','Debit',self.doc.name,''],
['Expenses','','Group','Yes','Expense Account','Debit',self.doc.name,''],
['Direct Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''],
- ['Cost of Goods Sold','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
- ['Expenses Included In Valuation','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
- ['Stock Adjustment','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
+ ['Stock Expenses','Direct Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''],
+ ['Cost of Goods Sold','Stock Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
+ ['Stock Adjustment','Stock Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
+ ['Expenses Included In Valuation', "Stock Expenses", 'Ledger', 'Yes', 'Expense Account', 'Debit', self.doc.name, ''],
['Indirect Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''],
['Advertising and Publicity','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''],
['Bad Debts Written Off','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
@@ -101,12 +103,14 @@
['Shareholders Funds','Capital Account','Group','No','','Credit',self.doc.name,''],
['Current Liabilities','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Accounts Payable','Current Liabilities','Group','No','','Credit',self.doc.name,''],
+ ['Stock Liabilities','Current Liabilities','Group','No','','Credit',self.doc.name,''],
+ ['Stock Received But Not Billed', 'Stock Liabilities', 'Ledger',
+ 'No', '', 'Credit', self.doc.name, ''],
['Duties and Taxes','Current Liabilities','Group','No','','Credit',self.doc.name,''],
['Loans (Liabilities)','Current Liabilities','Group','No','','Credit',self.doc.name,''],
['Secured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Unsecured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Bank Overdraft Account','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''],
- ['Stock Received But Not Billed','Current Liabilities','Ledger','No','','Credit',self.doc.name,''],
['Temporary Accounts (Liabilities)','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Temporary Account (Liabilities)','Temporary Accounts (Liabilities)','Ledger','No','','Credit',self.doc.name,'']
]
@@ -186,14 +190,35 @@
self.doc.letter_head = header
- # Set default AR and AP group
- # ---------------------------------------------------
- def set_default_groups(self):
- if not self.doc.receivables_group:
- webnotes.conn.set(self.doc, 'receivables_group', 'Accounts Receivable - '+self.doc.abbr)
- if not self.doc.payables_group:
- webnotes.conn.set(self.doc, 'payables_group', 'Accounts Payable - '+self.doc.abbr)
+ def set_default_accounts(self):
+ if not self.doc.receivables_group and webnotes.conn.exists('Account',
+ 'Accounts Receivable - ' + self.doc.abbr):
+ webnotes.conn.set(self.doc, 'receivables_group', 'Accounts Receivable - ' +
+ self.doc.abbr)
+
+ if not self.doc.payables_group and webnotes.conn.exists('Account',
+ 'Accounts Payable - ' + self.doc.abbr):
+ webnotes.conn.set(self.doc, 'payables_group', 'Accounts Payable - ' + self.doc.abbr)
+ if not self.doc.stock_delivered_but_not_billed and webnotes.conn.exists("Account",
+ "Stock Delivered But Not Billed - " + self.doc.abbr):
+ webnotes.conn.set(self.doc, "stock_delivered_but_not_billed",
+ "Stock Delivered But Not Billed - " + self.doc.abbr)
+
+ if not self.doc.stock_received_but_not_billed and webnotes.conn.exists("Account",
+ "Stock Received But Not Billed - " + self.doc.abbr):
+ webnotes.conn.set(self.doc, "stock_received_but_not_billed",
+ "Stock Received But Not Billed - " + self.doc.abbr)
+
+ if not self.doc.stock_adjustment_account and webnotes.conn.exists("Account",
+ "Stock Adjustment - " + self.doc.abbr):
+ webnotes.conn.set(self.doc, "stock_adjustment_account", "Stock Adjustment - " +
+ self.doc.abbr)
+
+ if not self.doc.expenses_included_in_valuation and webnotes.conn.exists("Account",
+ "Expenses Included In Valuation - " + self.doc.abbr):
+ webnotes.conn.set(self.doc, "expenses_included_in_valuation",
+ "Expenses Included In Valuation - " + self.doc.abbr)
# Create default cost center
# ---------------------------------------------------
@@ -228,7 +253,7 @@
self.doc.name)
if not ac:
self.create_default_accounts()
- self.set_default_groups()
+ self.set_default_accounts()
cc = sql("select name from `tabCost Center` where cost_center_name = 'Root' and company_name = '%s'"%(self.doc.name))
if not cc:
self.create_default_cost_center()
@@ -258,9 +283,6 @@
#update value as blank for tabSingles Global Defaults
sql("update `tabSingles` set value = '' where doctype='Global Defaults' and field = 'default_company' and value = %s", self.doc.name)
-
- # on rename
- # ---------
def on_rename(self,newdn,olddn):
sql("update `tabCompany` set company_name = '%s' where name = '%s'" %(newdn,olddn))
sql("update `tabSingles` set value = %s where doctype='Global Defaults' and field = 'default_company' and value = %s", (newdn, olddn))
diff --git a/setup/doctype/company/company.txt b/setup/doctype/company/company.txt
index d97cfc3..4d2dcda 100644
--- a/setup/doctype/company/company.txt
+++ b/setup/doctype/company/company.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-22 01:27:54",
+ "creation": "2013-02-27 09:38:05",
"docstatus": 0,
- "modified": "2013-02-26 10:57:39",
+ "modified": "2013-03-19 12:52:00",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -125,17 +125,6 @@
"options": "Account"
},
{
- "depends_on": "eval:!doc.__islocal",
- "description": "This account will be used to maintain value of available stock",
- "doctype": "DocField",
- "fieldname": "stock_in_hand_account",
- "fieldtype": "Link",
- "label": "Stock In Hand Account",
- "no_copy": 1,
- "options": "Account",
- "read_only": 0
- },
- {
"doctype": "DocField",
"fieldname": "column_break0",
"fieldtype": "Column Break",
@@ -182,6 +171,57 @@
"options": "\nWarn\nIgnore\nStop"
},
{
+ "depends_on": "eval:!doc.__islocal && sys_defaults.auto_inventory_accounting",
+ "doctype": "DocField",
+ "fieldname": "auto_inventory_accounting_settings",
+ "fieldtype": "Section Break",
+ "label": "Auto Inventory Accounting Settings"
+ },
+ {
+ "description": "This account will be used to maintain value of available stock",
+ "doctype": "DocField",
+ "fieldname": "stock_in_hand_account",
+ "fieldtype": "Link",
+ "label": "Stock In Hand Account",
+ "no_copy": 1,
+ "options": "Account",
+ "read_only": 0
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "stock_adjustment_account",
+ "fieldtype": "Link",
+ "label": "Stock Adjustment Account",
+ "options": "Account"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "expenses_included_in_valuation",
+ "fieldtype": "Link",
+ "label": "Expenses Included In Valuation",
+ "options": "Account"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "col_break23",
+ "fieldtype": "Column Break",
+ "width": "50%"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "stock_delivered_but_not_billed",
+ "fieldtype": "Link",
+ "label": "Stock Delivered But Not Billed",
+ "options": "Account"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "stock_received_but_not_billed",
+ "fieldtype": "Link",
+ "label": "Stock Received But Not Billed",
+ "options": "Account"
+ },
+ {
"description": "For reference only.",
"doctype": "DocField",
"fieldname": "company_info",
diff --git a/setup/doctype/global_defaults/global_defaults.py b/setup/doctype/global_defaults/global_defaults.py
index 6f3ab4a..8d94a03 100644
--- a/setup/doctype/global_defaults/global_defaults.py
+++ b/setup/doctype/global_defaults/global_defaults.py
@@ -43,6 +43,7 @@
'maintain_same_rate' : 'maintain_same_rate',
'session_expiry': 'session_expiry',
'disable_rounded_total': 'disable_rounded_total',
+ "update_stock": "update_stock",
}
class DocType:
diff --git a/setup/doctype/global_defaults/global_defaults.txt b/setup/doctype/global_defaults/global_defaults.txt
index 960da7e..6317439 100644
--- a/setup/doctype/global_defaults/global_defaults.txt
+++ b/setup/doctype/global_defaults/global_defaults.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-19 12:28:27",
+ "creation": "2013-02-21 14:54:43",
"docstatus": 0,
- "modified": "2013-02-20 14:09:00",
+ "modified": "2013-03-19 14:46:49",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -250,6 +250,13 @@
"fieldtype": "Column Break"
},
{
+ "description": "If checked, then in POS Sales Invoice, Update Stock gets checked by default",
+ "doctype": "DocField",
+ "fieldname": "update_stock",
+ "fieldtype": "Check",
+ "label": "Update Stock when using POS Sales Invoice"
+ },
+ {
"doctype": "DocField",
"fieldname": "account_info",
"fieldtype": "HTML",
@@ -403,7 +410,7 @@
"fieldname": "emp_created_by",
"fieldtype": "Select",
"label": "Employee Records to be created by ",
- "options": "\nNaming Series\nEmployee Number"
+ "options": "Naming Series\nEmployee Number"
},
{
"doctype": "DocField",
diff --git a/setup/doctype/sales_person/test_sales_person.py b/setup/doctype/sales_person/test_sales_person.py
index 5af4509..2dea3e5 100644
--- a/setup/doctype/sales_person/test_sales_person.py
+++ b/setup/doctype/sales_person/test_sales_person.py
@@ -4,5 +4,19 @@
"sales_person_name": "_Test Sales Person",
"parent_sales_person": "All Sales Persons",
"is_group": "No"
+ }],
+ [{
+ "doctype": "Sales Person",
+ "sales_person_name": "_Test Sales Person 1",
+ "parent_sales_person": "All Sales Persons",
+ "is_group": "No"
+ }],
+ [{
+ "doctype": "Sales Person",
+ "sales_person_name": "_Test Sales Person 2",
+ "parent_sales_person": "All Sales Persons",
+ "is_group": "No"
}]
+
+
]
\ No newline at end of file
diff --git a/setup/doctype/series_detail/series_detail.txt b/setup/doctype/series_detail/series_detail.txt
index 19ef3fb..98a5d78 100644
--- a/setup/doctype/series_detail/series_detail.txt
+++ b/setup/doctype/series_detail/series_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:25",
+ "creation": "2013-02-22 01:27:57",
"docstatus": 0,
- "modified": "2012-03-27 14:36:25",
+ "modified": "2013-03-07 07:03:32",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Setup",
- "name": "__common__",
- "section_style": "Tray",
- "show_in_menu": 0,
- "version": 3
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -41,7 +38,6 @@
"fieldtype": "Check",
"label": "Remove",
"oldfieldname": "remove",
- "oldfieldtype": "Check",
- "trigger": "Client"
+ "oldfieldtype": "Check"
}
]
\ No newline at end of file
diff --git a/setup/doctype/setup_control/setup_control.py b/setup/doctype/setup_control/setup_control.py
index 00cf1de..5bfe4a7 100644
--- a/setup/doctype/setup_control/setup_control.py
+++ b/setup/doctype/setup_control/setup_control.py
@@ -97,7 +97,7 @@
self.create_email_digest()
webnotes.clear_cache()
- msgprint("Company setup is complete")
+ msgprint("Company setup is complete. Please refresh the page before continuing.")
import webnotes.utils
user_fullname = (args.get('first_name') or '') + (args.get('last_name')
diff --git a/setup/doctype/sms_parameter/sms_parameter.txt b/setup/doctype/sms_parameter/sms_parameter.txt
index 55f90be..cc7a002 100755
--- a/setup/doctype/sms_parameter/sms_parameter.txt
+++ b/setup/doctype/sms_parameter/sms_parameter.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:25",
+ "creation": "2013-02-22 01:27:58",
"docstatus": 0,
- "modified": "2012-03-27 14:36:25",
+ "modified": "2013-03-07 07:03:32",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Setup",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 4
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -23,6 +20,7 @@
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
+ "print_width": "150px",
"reqd": 1,
"width": "150px"
},
diff --git a/setup/doctype/target_detail/target_detail.txt b/setup/doctype/target_detail/target_detail.txt
index 21b6323..b3e2886 100644
--- a/setup/doctype/target_detail/target_detail.txt
+++ b/setup/doctype/target_detail/target_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:24",
+ "creation": "2013-02-22 01:27:58",
"docstatus": 0,
- "modified": "2013-01-23 16:52:10",
+ "modified": "2013-03-07 07:03:33",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/setup/doctype/workflow_action_detail/workflow_action_detail.txt b/setup/doctype/workflow_action_detail/workflow_action_detail.txt
index 2ef95fd..7393882 100644
--- a/setup/doctype/workflow_action_detail/workflow_action_detail.txt
+++ b/setup/doctype/workflow_action_detail/workflow_action_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:26",
+ "creation": "2013-02-22 01:27:59",
"docstatus": 0,
- "modified": "2012-03-27 14:36:26",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
"owner": "swarnalata@webnotestech.com"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Setup",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 5
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -22,6 +19,7 @@
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
+ "print_width": "200px",
"width": "200px"
},
{
diff --git a/setup/doctype/workflow_rule_detail/workflow_rule_detail.txt b/setup/doctype/workflow_rule_detail/workflow_rule_detail.txt
index 73c1cf3..1aee3fe 100644
--- a/setup/doctype/workflow_rule_detail/workflow_rule_detail.txt
+++ b/setup/doctype/workflow_rule_detail/workflow_rule_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:26",
+ "creation": "2013-02-22 01:27:59",
"docstatus": 0,
- "modified": "2012-03-27 14:36:26",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
"owner": "swarnalata@webnotestech.com"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Setup",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 9
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -35,6 +32,7 @@
"oldfieldname": "rule_field",
"oldfieldtype": "Select",
"options": "[]",
+ "print_width": "200px",
"width": "200px"
},
{
@@ -53,6 +51,7 @@
"label": "Value",
"oldfieldname": "value",
"oldfieldtype": "Data",
+ "print_width": "100px",
"width": "100px"
},
{
@@ -70,6 +69,7 @@
"label": "Message when Cond. False",
"oldfieldname": "message",
"oldfieldtype": "Data",
+ "print_width": "200px",
"width": "200px"
},
{
diff --git a/setup/page/setup/setup.js b/setup/page/setup/setup.js
index 1d8a5ba..a9df459 100644
--- a/setup/page/setup/setup.js
+++ b/setup/page/setup/setup.js
@@ -45,7 +45,7 @@
},
{
"doctype":"Workflow",
- label:wn._("Workfow"),
+ label:wn._("Workflow"),
"description":wn._("Set workflow rules.")
},
{
@@ -98,12 +98,6 @@
label:wn._("Print Heading"),
"description":wn._("Add headers for standard print formats")
},
- {
- "route":"Form/Style Settings/Style Settings",
- doctype:wn._("Style Settings"),
- label:wn._("Style Settings"),
- "description":wn._("Change background fonts etc")
- }
]
},
{
@@ -186,19 +180,19 @@
},
]
},
- // {
- // title: wn._("Backups"),
- // icon: "icon-cloud-upload",
- // right: true,
- // items: [
- // {
- // "route":"Form/Backup Manager",
- // doctype:"Backup Manager",
- // label: wn._("Backup Manager"),
- // "description":wn._("Sync backups with remote tools like Dropbox etc.")
- // },
- // ]
- // },
+ {
+ title: wn._("Backups"),
+ icon: "icon-cloud-upload",
+ right: true,
+ items: [
+ {
+ "route":"Form/Backup Manager",
+ doctype:"Backup Manager",
+ label: wn._("Backup Manager"),
+ "description":wn._("Sync backups with remote tools like Dropbox etc.")
+ },
+ ]
+ },
]
pscript['onload_Setup'] = function(wrapper) {
diff --git a/startup/report_data_map.py b/startup/report_data_map.py
index ba3b546..f914277 100644
--- a/startup/report_data_map.py
+++ b/startup/report_data_map.py
@@ -86,8 +86,9 @@
"order_by": "name"
},
"Stock Ledger Entry": {
- "columns": ["name", "posting_date", "posting_time", "item_code", "warehouse", "actual_qty as qty",
- "voucher_type", "voucher_no", "ifnull(incoming_rate,0) as incoming_rate", "stock_uom"],
+ "columns": ["name", "posting_date", "posting_time", "item_code", "warehouse",
+ "actual_qty as qty", "voucher_type", "voucher_no",
+ "ifnull(incoming_rate,0) as incoming_rate", "stock_uom", "serial_no"],
"conditions": ["ifnull(is_cancelled, 'No')='No'"],
"order_by": "posting_date, posting_time, name",
"links": {
diff --git a/startup/schedule_handlers.py b/startup/schedule_handlers.py
index c710c54..0799817 100644
--- a/startup/schedule_handlers.py
+++ b/startup/schedule_handlers.py
@@ -51,8 +51,13 @@
from webnotes.utils.email_lib.bulk import clear_outbox
run_fn(clear_outbox)
+ # daily backup
+ from setup.doctype.backup_manager.backup_manager import take_backups_daily
+ take_backups_daily()
+
def execute_weekly():
- pass
+ from setup.doctype.backup_manager.backup_manager import take_backups_weekly
+ take_backups_weekly()
def execute_monthly():
pass
diff --git a/stock/doctype/bin/bin.py b/stock/doctype/bin/bin.py
index 37ecf85..be34312 100644
--- a/stock/doctype/bin/bin.py
+++ b/stock/doctype/bin/bin.py
@@ -16,15 +16,8 @@
from __future__ import unicode_literals
import webnotes
-from webnotes import _
-
-from webnotes.utils import add_days, cint, cstr, flt, now, nowdate, \
- get_url_to_form, formatdate
-from webnotes.model import db_exists
-from webnotes.model.doc import Document, addchild
-from webnotes.model.bean import copy_doclist
-from webnotes.model.code import get_obj
-from webnotes import msgprint
+from webnotes.utils import add_days, cint,flt, nowdate, get_url_to_form, formatdate
+from webnotes import msgprint, _
sql = webnotes.conn.sql
import webnotes.defaults
@@ -61,7 +54,7 @@
from stock.stock_ledger import update_entries_after
if not args.get("posting_date"):
- posting_date = nowdate()
+ args["posting_date"] = nowdate()
# update valuation and qty after transaction for post dated entry
update_entries_after({
@@ -70,7 +63,7 @@
"posting_date": args.get("posting_date"),
"posting_time": args.get("posting_time")
})
-
+
def update_qty(self, args):
# update the stock values (for current quantities)
self.doc.actual_qty = flt(self.doc.actual_qty) + flt(args.get("actual_qty"))
@@ -83,11 +76,11 @@
flt(self.doc.indented_qty) + flt(self.doc.planned_qty) - flt(self.doc.reserved_qty)
self.doc.save()
-
+
if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \
and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No':
self.reorder_item(args.get("voucher_type"), args.get("voucher_no"))
-
+
def get_first_sle(self):
sle = sql("""
select * from `tabStock Ledger Entry`
@@ -108,11 +101,10 @@
#check if re-order is required
item_reorder = webnotes.conn.get("Item Reorder",
{"parent": self.doc.item_code, "warehouse": self.doc.warehouse})
-
if item_reorder:
reorder_level = item_reorder.warehouse_reorder_level
reorder_qty = item_reorder.warehouse_reorder_qty
- material_request_type = item_reorder.material_request_type
+ material_request_type = item_reorder.material_request_type or "Purchase"
else:
reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code,
["re_order_level", "re_order_qty"])
@@ -123,7 +115,7 @@
material_request_type)
def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty,
- material_request_type):
+ material_request_type="Purchase"):
""" Create indent on reaching reorder level """
defaults = webnotes.defaults.get_defaults()
item = webnotes.doc("Item", self.doc.item_code)
@@ -151,7 +143,6 @@
"qty": reorder_qty,
"brand": item.brand,
}])
-
mr.insert()
mr.submit()
diff --git a/stock/doctype/delivery_note/delivery_note.js b/stock/doctype/delivery_note/delivery_note.js
index a8af107..7e6031c 100644
--- a/stock/doctype/delivery_note/delivery_note.js
+++ b/stock/doctype/delivery_note/delivery_note.js
@@ -308,4 +308,24 @@
if(cint(wn.boot.notification_settings.delivery_note)) {
cur_frm.email_doc(wn.boot.notification_settings.delivery_note_message);
}
+}
+
+// expense account
+cur_frm.fields_dict['delivery_note_details'].grid.get_field('expense_account').get_query = function(doc) {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": {
+ "is_pl_account": "Yes",
+ "debit_or_credit": "Debit",
+ "company": doc.company
+ }
+ }
+}
+
+// cost center
+cur_frm.fields_dict["delivery_note_details"].grid.get_field("cost_center").get_query = function(doc) {
+ return {
+ query: "accounts.utils.get_cost_center_list",
+ filters: { company_name: doc.company}
+ }
}
\ No newline at end of file
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index 35d008b..5e3c9e9 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -17,14 +17,13 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import cstr, flt, getdate
+from webnotes.utils import cstr, flt, getdate, cint
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
from webnotes import msgprint
sql = webnotes.conn.sql
-
from controllers.selling_controller import SellingController
class DocType(SellingController):
@@ -133,7 +132,7 @@
super(DocType, self).validate()
import utilities
- utilities.validate_status(self.doc.status, ["Draft", "submitted", "Cancelled"])
+ utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Cancelled"])
self.so_required()
self.validate_fiscal_year()
@@ -145,6 +144,8 @@
self.validate_mandatory()
self.validate_reference_value()
self.validate_for_items()
+ self.validate_warehouse()
+
sales_com_obj.validate_max_discount(self, 'delivery_note_details')
sales_com_obj.get_allocated_sum(self)
sales_com_obj.check_conversion_rate(self)
@@ -156,7 +157,7 @@
if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
if not self.doc.installation_status: self.doc.installation_status = 'Not Installed'
-
+
def validate_mandatory(self):
if self.doc.amended_from and not self.doc.amendment_date:
msgprint("Please Enter Amendment Date")
@@ -204,6 +205,12 @@
else:
chk_dupl_itm.append(f)
+ def validate_warehouse(self):
+ for d in self.get_item_list():
+ if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
+ if not d['warehouse']:
+ msgprint("Please enter Warehouse for item %s as it is stock item"
+ % d['item_code'], raise_exception=1)
def validate_items_with_prevdoc(self, d):
"""check if same item, warehouse present in prevdoc"""
@@ -225,7 +232,12 @@
bin = sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
-
+
+ def on_update(self):
+ self.doclist = get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
+ sl = get_obj('Stock Ledger')
+ sl.scrub_serial_nos(self)
+ sl.scrub_serial_nos(self, 'packing_details')
def on_submit(self):
self.validate_packed_qty()
@@ -251,6 +263,9 @@
self.update_stock_ledger(update_stock = 1)
self.credit_limit()
+
+ self.set_buying_amount()
+ self.make_gl_entries()
# set DN status
webnotes.conn.set(self.doc, 'status', 'Submitted')
@@ -293,6 +308,8 @@
self.update_stock_ledger(update_stock = -1)
webnotes.conn.set(self.doc, 'status', 'Cancelled')
self.cancel_packing_slips()
+
+ self.make_gl_entries()
def check_next_docstatus(self):
@@ -328,10 +345,10 @@
self.values = []
for d in self.get_item_list():
if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
- if not d['warehouse']:
- msgprint("Please enter Warehouse for item %s as it is stock item"
- % d['item_code'], raise_exception=1)
-
+ # this happens when item is changed from non-stock to stock item
+ if not d["warehouse"]:
+ continue
+
if d['reserved_qty'] < 0 :
# Reduce reserved qty from reserved warehouse mentioned in so
args = {
@@ -383,10 +400,18 @@
if amount != 0:
total = (amount/self.doc.net_total)*self.doc.grand_total
get_obj('Sales Common').check_credit(self, total)
-
-
- def on_update(self):
- self.doclist = get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
- sl = get_obj('Stock Ledger')
- sl.scrub_serial_nos(self)
- sl.scrub_serial_nos(self, 'packing_details')
\ No newline at end of file
+
+ def make_gl_entries(self):
+ if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
+ return
+
+ gl_entries = []
+ for item in self.doclist.get({"parentfield": "delivery_note_details"}):
+ self.check_expense_account(item)
+
+ gl_entries += self.get_gl_entries_for_stock(item.expense_account, -1*item.buying_amount,
+ cost_center=item.cost_center)
+
+ if gl_entries:
+ from accounts.general_ledger import make_gl_entries
+ make_gl_entries(gl_entries)
diff --git a/stock/doctype/delivery_note/test_delivery_note.py b/stock/doctype/delivery_note/test_delivery_note.py
index 4666360..d0ec631 100644
--- a/stock/doctype/delivery_note/test_delivery_note.py
+++ b/stock/doctype/delivery_note/test_delivery_note.py
@@ -1,3 +1,94 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+from __future__ import unicode_literals
+import unittest
+import webnotes
+import webnotes.defaults
+from webnotes.utils import cint
+
+class TestDeliveryNote(unittest.TestCase):
+ def _insert_purchase_receipt(self):
+ from stock.doctype.purchase_receipt.test_purchase_receipt import test_records as pr_test_records
+ pr = webnotes.bean(copy=pr_test_records[0])
+ pr.run_method("calculate_taxes_and_totals")
+ pr.insert()
+ pr.submit()
+
+ def test_delivery_note_no_gl_entry(self):
+ webnotes.conn.sql("""delete from `tabBin`""")
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+ self.assertEqual(cint(webnotes.defaults.get_global_default("auto_inventory_accounting")), 0)
+
+ self._insert_purchase_receipt()
+
+ dn = webnotes.bean(copy=test_records[0])
+ dn.insert()
+ dn.submit()
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Delivery Note' and voucher_no=%s
+ order by account desc""", dn.doc.name, as_dict=1)
+
+ self.assertTrue(not gl_entries)
+
+ def test_delivery_note_gl_entry(self):
+ webnotes.conn.sql("""delete from `tabBin`""")
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+ self.assertEqual(cint(webnotes.defaults.get_global_default("auto_inventory_accounting")), 1)
+
+ self._insert_purchase_receipt()
+
+ dn = webnotes.bean(copy=test_records[0])
+ dn.doclist[1].expense_account = "Cost of Goods Sold - _TC"
+ dn.doclist[1].cost_center = "Auto Inventory Accounting - _TC"
+
+ stock_in_hand_account = webnotes.conn.get_value("Company", dn.doc.company,
+ "stock_in_hand_account")
+
+ from accounts.utils import get_balance_on
+ prev_bal = get_balance_on(stock_in_hand_account, dn.doc.posting_date)
+
+ dn.insert()
+ dn.submit()
+
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Delivery Note' and voucher_no=%s
+ order by account asc""", dn.doc.name, as_dict=1)
+ self.assertTrue(gl_entries)
+
+ expected_values = sorted([
+ [stock_in_hand_account, 0.0, 375.0],
+ ["Cost of Goods Sold - _TC", 375.0, 0.0]
+ ])
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_values[i][0], gle.account)
+ self.assertEquals(expected_values[i][1], gle.debit)
+ self.assertEquals(expected_values[i][2], gle.credit)
+
+ # check stock in hand balance
+ bal = get_balance_on(stock_in_hand_account, dn.doc.posting_date)
+ self.assertEquals(bal, prev_bal - 375.0)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
test_records = [
[
{
@@ -15,18 +106,19 @@
"price_list_name": "_Test Price List",
"status": "Draft",
"territory": "_Test Territory",
+ "net_total": 500.0,
"grand_total": 500.0,
"grand_total_export": 500.0,
},
{
"description": "CPU",
"doctype": "Delivery Note Item",
- "item_code": "_Test Item Home Desktop 100",
- "item_name": "CPU",
+ "item_code": "_Test Item",
+ "item_name": "_Test Item",
"parentfield": "delivery_note_details",
- "qty": 4.0,
- "basic_rate": 50.0,
- "export_rate": 50.0,
+ "qty": 5.0,
+ "basic_rate": 100.0,
+ "export_rate": 100.0,
"amount": 500.0,
"warehouse": "_Test Warehouse",
"stock_uom": "No."
diff --git a/stock/doctype/delivery_note_item/delivery_note_item.txt b/stock/doctype/delivery_note_item/delivery_note_item.txt
index 9f18568..94c6541 100644
--- a/stock/doctype/delivery_note_item/delivery_note_item.txt
+++ b/stock/doctype/delivery_note_item/delivery_note_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:26",
+ "creation": "2013-03-07 11:42:59",
"docstatus": 0,
- "modified": "2013-01-29 16:27:56",
+ "modified": "2013-03-21 18:36:22",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -30,7 +30,8 @@
"fieldname": "barcode",
"fieldtype": "Data",
"label": "Barcode",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -41,6 +42,8 @@
"oldfieldname": "item_code",
"oldfieldtype": "Link",
"options": "Item",
+ "print_width": "150px",
+ "read_only": 0,
"reqd": 1,
"search_index": 1,
"width": "150px"
@@ -62,6 +65,8 @@
"oldfieldname": "item_name",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
+ "read_only": 0,
"reqd": 1,
"width": "150px"
},
@@ -72,6 +77,8 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Small Text",
+ "print_width": "300px",
+ "read_only": 0,
"reqd": 1,
"width": "300px"
},
@@ -83,6 +90,8 @@
"label": "Quantity",
"oldfieldname": "qty",
"oldfieldtype": "Currency",
+ "print_width": "100px",
+ "read_only": 0,
"reqd": 1,
"width": "100px"
},
@@ -94,6 +103,7 @@
"oldfieldname": "stock_uom",
"oldfieldtype": "Data",
"print_hide": 0,
+ "print_width": "50px",
"read_only": 1,
"reqd": 1,
"width": "50px"
@@ -109,6 +119,8 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 1,
+ "print_width": "100px",
+ "read_only": 0,
"reqd": 0,
"width": "100px"
},
@@ -121,6 +133,8 @@
"oldfieldname": "adj_rate",
"oldfieldtype": "Float",
"print_hide": 1,
+ "print_width": "100px",
+ "read_only": 0,
"width": "100px"
},
{
@@ -132,6 +146,8 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 0,
+ "print_width": "150px",
+ "read_only": 0,
"reqd": 0,
"width": "150px"
},
@@ -144,6 +160,7 @@
"oldfieldtype": "Currency",
"options": "currency",
"print_hide": 0,
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"width": "100px"
@@ -157,6 +174,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -170,6 +188,8 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "150px",
+ "read_only": 0,
"reqd": 0,
"width": "150px"
},
@@ -182,6 +202,7 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"reqd": 0,
"width": "100px"
@@ -195,6 +216,8 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"print_hide": 1,
+ "print_width": "100px",
+ "read_only": 0,
"width": "100px"
},
{
@@ -206,17 +229,42 @@
"no_copy": 1,
"oldfieldname": "serial_no",
"oldfieldtype": "Text",
- "print_hide": 0
+ "print_hide": 0,
+ "read_only": 0
},
{
"doctype": "DocField",
"fieldname": "batch_no",
"fieldtype": "Link",
+ "hidden": 0,
"label": "Batch No",
"oldfieldname": "batch_no",
"oldfieldtype": "Link",
"options": "Batch",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "expense_account",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Expense Account",
+ "no_copy": 1,
+ "options": "Account",
+ "print_hide": 1,
+ "width": "120px"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Cost Center",
+ "no_copy": 1,
+ "options": "Cost Center",
+ "print_hide": 1,
+ "width": "120px"
},
{
"doctype": "DocField",
@@ -240,6 +288,7 @@
"oldfieldtype": "Link",
"options": "Brand",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
},
@@ -252,6 +301,7 @@
"oldfieldname": "actual_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
},
@@ -263,6 +313,7 @@
"no_copy": 1,
"options": "currency",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -275,6 +326,7 @@
"oldfieldname": "installed_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"width": "150px"
},
@@ -299,6 +351,7 @@
"oldfieldname": "prevdoc_doctype",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
@@ -314,6 +367,7 @@
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
@@ -340,6 +394,7 @@
"oldfieldname": "prevdoc_detail_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"search_index": 0,
"width": "150px"
@@ -356,6 +411,17 @@
"read_only": 1
},
{
+ "doctype": "DocField",
+ "fieldname": "buying_amount",
+ "fieldtype": "Currency",
+ "hidden": 1,
+ "label": "Buying Amount",
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "print_hide": 1,
+ "read_only": 1
+ },
+ {
"allow_on_submit": 1,
"doctype": "DocField",
"fieldname": "page_break",
@@ -363,6 +429,7 @@
"label": "Page Break",
"oldfieldname": "page_break",
"oldfieldtype": "Check",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
}
]
\ No newline at end of file
diff --git a/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt b/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
index 853e94e..defd39d 100644
--- a/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
+++ b/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:27",
+ "creation": "2013-02-22 01:28:00",
"docstatus": 0,
- "modified": "2013-01-22 14:46:40",
+ "modified": "2013-03-07 07:03:20",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -74,6 +74,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "300px",
"read_only": 1,
"width": "300px"
},
diff --git a/stock/doctype/featured_item/featured_item.txt b/stock/doctype/featured_item/featured_item.txt
index a08e282..5c91e87 100644
--- a/stock/doctype/featured_item/featured_item.txt
+++ b/stock/doctype/featured_item/featured_item.txt
@@ -1,33 +1,33 @@
[
{
- "owner": "Administrator",
+ "creation": "2013-02-22 01:28:00",
"docstatus": 0,
- "creation": "2012-12-07 14:28:33",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
- "modified": "2012-12-07 14:28:33"
+ "owner": "Administrator"
},
{
- "istable": 1,
"description": "Featured Item in Item Group",
"doctype": "DocType",
+ "istable": 1,
"module": "Stock",
"name": "__common__"
},
{
- "parent": "Featured Item",
"doctype": "DocField",
- "name": "__common__",
- "label": "Item",
- "parenttype": "DocType",
- "options": "Item",
"fieldname": "item",
"fieldtype": "Link",
- "permlevel": 0,
- "parentfield": "fields"
+ "label": "Item",
+ "name": "__common__",
+ "options": "Item",
+ "parent": "Featured Item",
+ "parentfield": "fields",
+ "parenttype": "DocType",
+ "permlevel": 0
},
{
- "name": "Featured Item",
- "doctype": "DocType"
+ "doctype": "DocType",
+ "name": "Featured Item"
},
{
"doctype": "DocField"
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index 334af298..931b776 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -20,15 +20,12 @@
from webnotes.utils import cstr, flt
from webnotes.model.doc import addchild
from webnotes.model.bean import getlist
-from webnotes import msgprint
+from webnotes import msgprint, _
sql = webnotes.conn.sql
-class DocType:
- def __init__(self, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
-
+from webnotes.model.controller import DocListController
+class DocType(DocListController):
def get_tax_rate(self, tax_type):
rate = sql("select tax_rate from tabAccount where name = %s", tax_type)
ret = {
@@ -196,6 +193,8 @@
if self.doc.name:
self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name')
+
+ self.validate_is_stock_item()
def check_non_asset_warehouse(self):
if self.doc.is_asset_item == "Yes":
@@ -215,6 +214,15 @@
'description' : file and file[0]['description'] or ''
}
return ret
+
+ def validate_is_stock_item(self):
+ if not self.doc.fields.get("__islocal"):
+ if webnotes.conn.get_value("Item", self.doc.name, "is_stock_item")=="Yes" and \
+ ((not self.doc.is_stock_item) or self.doc.is_stock_item == "No"):
+ if self.check_if_sle_exists() == "exists":
+ webnotes.msgprint(self.meta.get_label("is_stock_item") + ": "
+ + _("""Cannot change to Yes. Reason: Stock Ledger Entries exist for""")
+ + """ "%s" """ % self.doc.name, raise_exception=True)
def check_if_sle_exists(self):
sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
@@ -230,8 +238,7 @@
from website.helpers.product import get_parent_item_groups, url_for_website
self.parent_groups = get_parent_item_groups(self.doc.item_group) + [{"name":self.doc.name}]
self.doc.website_image = url_for_website(self.doc.website_image)
- self.doc.title = self.doc.item_name == self.doc.name and self.doc.item_name or \
- (self.doc.item_name + " [" + self.doc.name + "]")
+ self.doc.title = self.doc.item_name
if self.doc.slideshow:
from website.helpers.slideshow import get_slideshow
diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt
index 1a48368..036b9d5 100644
--- a/stock/doctype/item/item.txt
+++ b/stock/doctype/item/item.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-02-21 14:54:43",
"docstatus": 0,
- "modified": "2013-02-28 10:43:02",
+ "modified": "2013-03-06 16:02:47",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -404,18 +404,6 @@
},
{
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
- "description": "Buying Cost will be updated from Purchase Orders and Purchase Receipts. <br>The buying cost will calculated by moving average method.",
- "doctype": "DocField",
- "fieldname": "buying_cost",
- "fieldtype": "Float",
- "label": "Buying Cost",
- "no_copy": 1,
- "oldfieldname": "buying_cost",
- "oldfieldtype": "Currency",
- "read_only": 1
- },
- {
- "depends_on": "eval:doc.is_purchase_item==\"Yes\"",
"doctype": "DocField",
"fieldname": "last_purchase_rate",
"fieldtype": "Float",
diff --git a/stock/doctype/item/test_item.py b/stock/doctype/item/test_item.py
index 035774b..f31f245 100644
--- a/stock/doctype/item/test_item.py
+++ b/stock/doctype/item/test_item.py
@@ -127,4 +127,23 @@
"is_sub_contracted_item": "Yes",
"stock_uom": "_Test UOM"
}],
+ [{
+ "doctype": "Item",
+ "item_code": "_Test Non Stock Item",
+ "item_name": "_Test Non Stock Item",
+ "description": "_Test Non Stock Item",
+ "item_group": "_Test Item Group Desktops",
+ "is_stock_item": "No",
+ "is_asset_item": "No",
+ "has_batch_no": "No",
+ "has_serial_no": "No",
+ "is_purchase_item": "Yes",
+ "is_sales_item": "Yes",
+ "is_service_item": "No",
+ "is_sample_item": "No",
+ "inspection_required": "No",
+ "is_pro_applicable": "No",
+ "is_sub_contracted_item": "No",
+ "stock_uom": "_Test UOM"
+ }],
]
\ No newline at end of file
diff --git a/stock/doctype/item_customer_detail/item_customer_detail.txt b/stock/doctype/item_customer_detail/item_customer_detail.txt
index 8535f1697..3b916a2 100644
--- a/stock/doctype/item_customer_detail/item_customer_detail.txt
+++ b/stock/doctype/item_customer_detail/item_customer_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:33",
+ "creation": "2013-03-08 15:37:16",
"docstatus": 0,
- "modified": "2012-03-27 14:36:33",
+ "modified": "2013-03-21 17:29:45",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,14 +10,11 @@
"autoname": "ITEMCUST/.#####",
"description": "For the convenience of customers, these codes can be used in print formats like Invoices and Delivery Notes",
"doctype": "DocType",
- "in_create": 1,
+ "in_create": 0,
"istable": 1,
"module": "Stock",
"name": "__common__",
- "read_only": 0,
- "section_style": "Tray",
- "show_in_menu": 0,
- "version": 7
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -42,6 +39,7 @@
"oldfieldname": "price_list_name",
"oldfieldtype": "Select",
"options": "Customer",
+ "print_width": "180px",
"width": "180px"
},
{
@@ -51,6 +49,7 @@
"label": "Ref Code",
"oldfieldname": "ref_rate",
"oldfieldtype": "Currency",
+ "print_width": "120px",
"width": "120px"
}
]
\ No newline at end of file
diff --git a/stock/doctype/item_price/item_price.txt b/stock/doctype/item_price/item_price.txt
index 687a35a..721902b 100644
--- a/stock/doctype/item_price/item_price.txt
+++ b/stock/doctype/item_price/item_price.txt
@@ -1,15 +1,15 @@
[
{
- "creation": "2013-01-21 18:19:14",
+ "creation": "2013-03-08 15:37:16",
"docstatus": 0,
- "modified": "2013-01-23 16:57:49",
+ "modified": "2013-03-21 17:29:15",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "RFD/.#####",
"doctype": "DocType",
- "in_create": 1,
+ "in_create": 0,
"istable": 1,
"module": "Stock",
"name": "__common__",
diff --git a/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.txt b/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.txt
index be9f99b..8233ede 100644
--- a/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.txt
+++ b/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:33",
+ "creation": "2013-02-22 01:28:01",
"docstatus": 0,
- "modified": "2012-03-27 14:36:33",
+ "modified": "2013-03-07 07:03:22",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -11,10 +11,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Stock",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 1
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -36,6 +33,7 @@
"in_filter": 0,
"label": "Parameter",
"oldfieldname": "specification",
+ "print_width": "200px",
"reqd": 1,
"search_index": 0,
"width": "200px"
diff --git a/stock/doctype/item_reorder/item_reorder.txt b/stock/doctype/item_reorder/item_reorder.txt
index ca429af..b6933c7 100644
--- a/stock/doctype/item_reorder/item_reorder.txt
+++ b/stock/doctype/item_reorder/item_reorder.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-18 12:48:07",
+ "creation": "2013-03-07 11:42:59",
"docstatus": 0,
- "modified": "2013-02-18 12:54:46",
+ "modified": "2013-03-19 12:22:44",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -20,7 +20,8 @@
"parent": "Item Reorder",
"parentfield": "fields",
"parenttype": "DocType",
- "permlevel": 0
+ "permlevel": 0,
+ "read_only": 0
},
{
"doctype": "DocType",
@@ -38,7 +39,8 @@
"doctype": "DocField",
"fieldname": "warehouse_reorder_level",
"fieldtype": "Float",
- "label": "Re-order Level"
+ "label": "Re-order Level",
+ "reqd": 1
},
{
"doctype": "DocField",
@@ -51,6 +53,7 @@
"fieldname": "material_request_type",
"fieldtype": "Select",
"label": "Material Request Type",
- "options": "Purchase\nTransfer"
+ "options": "Purchase\nTransfer",
+ "reqd": 1
}
]
\ No newline at end of file
diff --git a/stock/doctype/item_supplier/item_supplier.txt b/stock/doctype/item_supplier/item_supplier.txt
index 3569d25..3129504 100644
--- a/stock/doctype/item_supplier/item_supplier.txt
+++ b/stock/doctype/item_supplier/item_supplier.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:33",
+ "creation": "2013-02-22 01:28:01",
"docstatus": 0,
- "modified": "2012-03-27 14:36:33",
+ "modified": "2013-03-07 07:03:22",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Stock",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 3
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -39,6 +36,7 @@
"fieldname": "supplier_part_no",
"fieldtype": "Data",
"label": "Supplier Part Number",
+ "print_width": "200px",
"width": "200px"
}
]
\ No newline at end of file
diff --git a/stock/doctype/item_tax/item_tax.txt b/stock/doctype/item_tax/item_tax.txt
index a0bfb57..343f965 100644
--- a/stock/doctype/item_tax/item_tax.txt
+++ b/stock/doctype/item_tax/item_tax.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:27",
+ "creation": "2013-02-22 01:28:01",
"docstatus": 0,
- "modified": "2013-01-23 16:54:25",
+ "modified": "2013-03-07 07:03:22",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/stock/doctype/item_website_specification/item_website_specification.txt b/stock/doctype/item_website_specification/item_website_specification.txt
index db2bc9f..1b371c7 100644
--- a/stock/doctype/item_website_specification/item_website_specification.txt
+++ b/stock/doctype/item_website_specification/item_website_specification.txt
@@ -1,42 +1,44 @@
[
{
- "owner": "Administrator",
+ "creation": "2013-02-22 01:28:01",
"docstatus": 0,
- "creation": "2012-12-07 15:42:25",
+ "modified": "2013-03-07 07:03:22",
"modified_by": "Administrator",
- "modified": "2012-12-17 15:29:37"
+ "owner": "Administrator"
},
{
- "istable": 1,
"description": "Table for Item that will be shown in Web Site",
"doctype": "DocType",
+ "istable": 1,
"module": "Stock",
"name": "__common__"
},
{
+ "doctype": "DocField",
"name": "__common__",
"parent": "Item Website Specification",
- "doctype": "DocField",
+ "parentfield": "fields",
"parenttype": "DocType",
- "permlevel": 0,
- "parentfield": "fields"
+ "permlevel": 0
},
{
- "name": "Item Website Specification",
- "doctype": "DocType"
+ "doctype": "DocType",
+ "name": "Item Website Specification"
},
{
"doctype": "DocField",
- "label": "Label",
- "width": "150px",
"fieldname": "label",
- "fieldtype": "Data"
+ "fieldtype": "Data",
+ "label": "Label",
+ "print_width": "150px",
+ "width": "150px"
},
{
"doctype": "DocField",
- "label": "Description",
- "width": "300px",
"fieldname": "description",
- "fieldtype": "Text"
+ "fieldtype": "Text",
+ "label": "Description",
+ "print_width": "300px",
+ "width": "300px"
}
]
\ No newline at end of file
diff --git a/stock/doctype/landed_cost_item/landed_cost_item.txt b/stock/doctype/landed_cost_item/landed_cost_item.txt
index b299a27..1563fac 100644
--- a/stock/doctype/landed_cost_item/landed_cost_item.txt
+++ b/stock/doctype/landed_cost_item/landed_cost_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:27",
+ "creation": "2013-02-22 01:28:02",
"docstatus": 0,
- "modified": "2013-01-23 16:55:26",
+ "modified": "2013-03-07 07:03:23",
"modified_by": "Administrator",
"owner": "wasim@webnotestech.com"
},
@@ -42,6 +42,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Data",
+ "print_width": "300px",
"width": "300px"
},
{
diff --git a/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.txt b/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.txt
index 993c4f4..8b80559 100644
--- a/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.txt
+++ b/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:34",
+ "creation": "2013-02-22 01:28:02",
"docstatus": 0,
- "modified": "2012-03-27 14:36:34",
+ "modified": "2013-03-07 07:03:23",
"modified_by": "Administrator",
"owner": "wasim@webnotestech.com"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Stock",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 5
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -35,6 +32,7 @@
"oldfieldname": "purchase_receipt_no",
"oldfieldtype": "Link",
"options": "Purchase Receipt",
+ "print_width": "220px",
"width": "220px"
},
{
@@ -44,6 +42,7 @@
"label": "Select PR",
"oldfieldname": "include_in_landed_cost",
"oldfieldtype": "Check",
+ "print_width": "120px",
"width": "120px"
}
]
\ No newline at end of file
diff --git a/stock/doctype/material_request/material_request.py b/stock/doctype/material_request/material_request.py
index 7742676..8a899b3 100644
--- a/stock/doctype/material_request/material_request.py
+++ b/stock/doctype/material_request/material_request.py
@@ -105,6 +105,9 @@
import utilities
utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped",
"Cancelled"])
+
+ # restrict material request type
+ self.validate_value("material_request_type", "in", ["Purchase", "Transfer"])
# Get Purchase Common Obj
pc_obj = get_obj(dt='Purchase Common')
diff --git a/stock/doctype/material_request_item/material_request_item.txt b/stock/doctype/material_request_item/material_request_item.txt
index d608743..7d9a417 100644
--- a/stock/doctype/material_request_item/material_request_item.txt
+++ b/stock/doctype/material_request_item/material_request_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-20 13:25:31",
+ "creation": "2013-02-22 01:28:02",
"docstatus": 0,
- "modified": "2013-02-20 14:06:58",
+ "modified": "2013-03-07 07:03:25",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -35,6 +35,7 @@
"oldfieldname": "schedule_date",
"oldfieldtype": "Date",
"print_hide": 0,
+ "print_width": "100px",
"reqd": 1,
"width": "100px"
},
@@ -47,6 +48,7 @@
"oldfieldname": "item_code",
"oldfieldtype": "Link",
"options": "Item",
+ "print_width": "100px",
"reqd": 1,
"search_index": 1,
"width": "100px"
@@ -58,6 +60,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "250px",
"reqd": 1,
"width": "250px"
},
@@ -70,6 +73,7 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"print_hide": 0,
+ "print_width": "100px",
"reqd": 0,
"width": "100px"
},
@@ -82,6 +86,7 @@
"no_copy": 0,
"oldfieldname": "qty",
"oldfieldtype": "Currency",
+ "print_width": "80px",
"reqd": 1,
"width": "80px"
},
@@ -94,6 +99,7 @@
"oldfieldname": "uom",
"oldfieldtype": "Link",
"options": "UOM",
+ "print_width": "70px",
"read_only": 1,
"reqd": 1,
"width": "70px"
@@ -117,6 +123,7 @@
"label": "Item Name",
"oldfieldname": "item_name",
"oldfieldtype": "Data",
+ "print_width": "100px",
"reqd": 1,
"search_index": 1,
"width": "100px"
@@ -145,6 +152,7 @@
"oldfieldtype": "Link",
"options": "Brand",
"print_hide": 1,
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -157,6 +165,7 @@
"oldfieldname": "min_order_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "70px",
"read_only": 1,
"reqd": 0,
"width": "70px"
@@ -170,6 +179,7 @@
"oldfieldname": "projected_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "print_width": "70px",
"read_only": 1,
"width": "70px"
},
diff --git a/stock/doctype/packing_slip/packing_slip.js b/stock/doctype/packing_slip/packing_slip.js
index a332ca8..e9396d9 100644
--- a/stock/doctype/packing_slip/packing_slip.js
+++ b/stock/doctype/packing_slip/packing_slip.js
@@ -19,7 +19,8 @@
}
-cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
+cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query =
+ function(doc, cdt, cdn) {
var query = 'SELECT name, item_name, description FROM `tabItem` WHERE name IN ( \
SELECT item_code FROM `tabDelivery Note Item` dnd \
WHERE parent="' + doc.delivery_note + '" AND IFNULL(qty, 0) > IFNULL(packed_qty, 0)) AND %(key)s LIKE "%s" LIMIT 50';
@@ -28,23 +29,16 @@
// Fetch item details
-cur_frm.cscript.item_code = function(doc, cdt, cdn) {
- if(locals[cdt][cdn].item_code) {
- $c_obj(make_doclist(cdt, cdn), 'get_item_details', doc.delivery_note, function(r, rt) {
- if(r.exc) {
- msgprint(r.exc);
- } else {
- refresh_field('item_details');
- }
- });
- }
-}
-
+cur_frm.add_fetch("item_code", "item_name", "item_name");
+cur_frm.add_fetch("item_code", "stock_uom", "stock_uom");
+cur_frm.add_fetch("item_code", "net_weight", "net_weight");
+cur_frm.add_fetch("item_code", "weight_uom", "weight_uom");
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
+ console.log(make_doclist(cdt, cdn));
if(doc.delivery_note && doc.__islocal) {
var ps_detail = getchildren('Packing Slip Item', doc.name, 'item_details');
- if(!(flt(ps_detail[0].net_weight) && cstr(ps_detail[0].weight_uom))) {
+ if(!(flt(ps_detail.net_weight) && cstr(ps_detail.weight_uom))) {
cur_frm.cscript.update_item_details(doc);
}
}
diff --git a/stock/doctype/packing_slip/packing_slip.py b/stock/doctype/packing_slip/packing_slip.py
index 5f4fda0..72682b2 100644
--- a/stock/doctype/packing_slip/packing_slip.py
+++ b/stock/doctype/packing_slip/packing_slip.py
@@ -40,15 +40,12 @@
"""
Validates if delivery note has status as submitted
"""
- res = webnotes.conn.sql("""\
- SELECT docstatus FROM `tabDelivery Note`
- WHERE name=%(delivery_note)s
- """, self.doc.fields)
+ res = webnotes.conn.sql("""SELECT docstatus FROM `tabDelivery Note`
+ WHERE name=%(delivery_note)s""", self.doc.fields)
if not(res and res[0][0]==0):
webnotes.msgprint("""Invalid Delivery Note. Delivery Note should exist
- and should be in draft state. Please rectify and try again.""",
- raise_exception=1)
+ and should be in draft state. Please rectify and try again.""", raise_exception=1)
def validate_case_nos(self):
@@ -65,11 +62,10 @@
raise_exception=1)
- res = webnotes.conn.sql("""\
- SELECT name FROM `tabPacking Slip`
+ res = webnotes.conn.sql("""SELECT name FROM `tabPacking Slip`
WHERE delivery_note = %(delivery_note)s AND docstatus = 1 AND
(from_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s
- OR to_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s)\
+ OR to_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s)
""", self.doc.fields)
if res:
@@ -133,10 +129,10 @@
item['recommended_qty'] = (flt(item['qty']) - flt(item['packed_qty'])) / no_of_cases
item['specified_qty'] = flt(ps_item_qty[item['item_code']])
- webnotes.msgprint("""\
+ webnotes.msgprint("""
Invalid Quantity specified (%(specified_qty)s %(stock_uom)s).
%(packed_qty)s out of %(qty)s %(stock_uom)s already packed for %(item_code)s.
- <b>Recommended quantity for %(item_code)s = %(recommended_qty)s \
+ <b>Recommended quantity for %(item_code)s = %(recommended_qty)s
%(stock_uom)s</b>""" % item, raise_exception=1)
@@ -167,16 +163,15 @@
for item in dn_details:
new_packed_qty = flt(item['packed_qty'])
if (new_packed_qty < 0) or (new_packed_qty > flt(item['qty'])):
- webnotes.msgprint("Invalid new packed quantity for item %s. \
- Please try again or contact support@erpnext.com" % item['item_code'], raise_exception=1)
+ webnotes.msgprint("""Invalid new packed quantity for item %s.
+ Please try again or contact support@erpnext.com""" %
+ item['item_code'], raise_exception=1)
- webnotes.conn.sql("""\
- UPDATE `tabDelivery Note Item`
- SET packed_qty = %s
- WHERE parent = %s AND item_code = %s""",
+ webnotes.conn.sql("""UPDATE `tabDelivery Note Item`
+ SET packed_qty = %s WHERE parent = %s AND item_code = %s""",
(new_packed_qty, self.doc.delivery_note, item['item_code']))
- webnotes.conn.set_value("Delivery Note", self.doc.delivery_note,
- "modified", now())
+
+ webnotes.conn.set_value("Delivery Note", self.doc.delivery_note, "modified", now())
def update_item_details(self):
@@ -191,8 +186,7 @@
def set_item_details(self, row):
- res = webnotes.conn.sql("""\
- SELECT item_name, SUM(IFNULL(qty, 0)) as total_qty,
+ res = webnotes.conn.sql("""SELECT item_name, SUM(IFNULL(qty, 0)) as total_qty,
IFNULL(packed_qty, 0) as packed_qty, stock_uom
FROM `tabDelivery Note Item`
WHERE parent=%s AND item_code=%s GROUP BY item_code""",
@@ -203,10 +197,9 @@
if not row.qty:
row.qty = qty >= 0 and qty or 0
- res = webnotes.conn.sql("""\
- SELECT net_weight, weight_uom FROM `tabItem`
- WHERE name=%s""", self.doc.item_code, as_dict=1)
-
+ res = webnotes.conn.sql("""SELECT net_weight, weight_uom FROM `tabItem`
+ WHERE name=%s""", row.item_code, as_dict=1)
+
if res and len(res)>0:
row.net_weight = res[0]["net_weight"]
row.weight_uom = res[0]["weight_uom"]
@@ -217,8 +210,7 @@
Returns the next case no. for a new packing slip for a delivery
note
"""
- recommended_case_no = webnotes.conn.sql("""\
- SELECT MAX(to_case_no) FROM `tabPacking Slip`
+ recommended_case_no = webnotes.conn.sql("""SELECT MAX(to_case_no) FROM `tabPacking Slip`
WHERE delivery_note = %(delivery_note)s AND docstatus=1""", self.doc.fields)
return cint(recommended_case_no[0][0]) + 1
\ No newline at end of file
diff --git a/stock/doctype/packing_slip_item/packing_slip_item.py b/stock/doctype/packing_slip_item/packing_slip_item.py
new file mode 100644
index 0000000..928aa9f
--- /dev/null
+++ b/stock/doctype/packing_slip_item/packing_slip_item.py
@@ -0,0 +1,8 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+class DocType:
+ def __init__(self, d, dl):
+ self.doc, self.doclist = d, dl
\ No newline at end of file
diff --git a/stock/doctype/packing_slip_item/packing_slip_item.txt b/stock/doctype/packing_slip_item/packing_slip_item.txt
index c1e6abb..40ff066 100644
--- a/stock/doctype/packing_slip_item/packing_slip_item.txt
+++ b/stock/doctype/packing_slip_item/packing_slip_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:28",
+ "creation": "2013-02-22 01:28:02",
"docstatus": 0,
- "modified": "2013-01-22 14:47:04",
+ "modified": "2013-03-07 07:03:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -31,6 +31,7 @@
"fieldtype": "Link",
"label": "Item Code",
"options": "Item",
+ "print_width": "100px",
"reqd": 1,
"width": "100px"
},
@@ -39,6 +40,7 @@
"fieldname": "item_name",
"fieldtype": "Data",
"label": "Item Name",
+ "print_width": "200px",
"read_only": 1,
"width": "200px"
},
@@ -47,6 +49,7 @@
"fieldname": "qty",
"fieldtype": "Float",
"label": "Quantity",
+ "print_width": "100px",
"reqd": 1,
"width": "100px"
},
@@ -55,6 +58,7 @@
"fieldname": "stock_uom",
"fieldtype": "Data",
"label": "UOM",
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -63,6 +67,7 @@
"fieldname": "net_weight",
"fieldtype": "Float",
"label": "Net Weight",
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
@@ -72,6 +77,7 @@
"fieldtype": "Link",
"label": "Weight UOM",
"options": "UOM",
+ "print_width": "100px",
"read_only": 1,
"width": "100px"
},
diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py
index 12da0a6..7949a1c 100644
--- a/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -20,8 +20,7 @@
from webnotes.utils import cstr, flt, cint
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
-from webnotes.model.doc import Document
-from webnotes import msgprint, _
+from webnotes import msgprint
sql = webnotes.conn.sql
@@ -125,7 +124,7 @@
self.update_raw_materials_supplied("pr_raw_material_details")
self.update_valuation_rate("purchase_receipt_details")
-
+
def on_update(self):
if self.doc.rejected_warehouse:
for d in getlist(self.doclist,'purchase_receipt_details'):
@@ -146,6 +145,9 @@
self.values = []
for d in getlist(self.doclist, 'purchase_receipt_details'):
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
+ if not d.warehouse:
+ continue
+
ord_qty = 0
pr_qty = flt(d.qty) * flt(d.conversion_factor)
@@ -316,31 +318,13 @@
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
return
- abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
- stock_received_account = "Stock Received But Not Billed - %s" % (abbr,)
- stock_in_hand_account = self.get_stock_in_hand_account()
+ from accounts.general_ledger import make_gl_entries
+ against_stock_account = self.get_default_account("stock_received_but_not_billed")
total_valuation_amount = self.get_total_valuation_amount()
+ gl_entries = self.get_gl_entries_for_stock(against_stock_account, total_valuation_amount)
- if total_valuation_amount:
- gl_entries = [
- # debit stock in hand account
- self.get_gl_dict({
- "account": stock_in_hand_account,
- "against": stock_received_account,
- "debit": total_valuation_amount,
- "remarks": self.doc.remarks or "Accounting Entry for Stock",
- }, self.doc.docstatus == 2),
-
- # credit stock received but not billed account
- self.get_gl_dict({
- "account": stock_received_account,
- "against": stock_in_hand_account,
- "credit": total_valuation_amount,
- "remarks": self.doc.remarks or "Accounting Entry for Stock",
- }, self.doc.docstatus == 2),
- ]
- from accounts.general_ledger import make_gl_entries
+ if gl_entries:
make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2)
def get_total_valuation_amount(self):
diff --git a/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt b/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt
index 8c20d4c..7f4e827 100755
--- a/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt
+++ b/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-07 08:28:23",
+ "creation": "2013-02-22 01:28:03",
"docstatus": 0,
- "modified": "2013-02-11 08:13:11",
+ "modified": "2013-03-07 07:03:28",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/stock/doctype/sales_and_purchase_return_tool/__init__.py b/stock/doctype/sales_and_purchase_return_tool/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/_messages_doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/_messages_doc.json
deleted file mode 100644
index 979f20f..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/_messages_doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-[
- "Make Credit Note",
- "Make Excise Invoice",
- "Sales Return",
- "Get Items",
- "Delivery Note No",
- "Company",
- "Customer/Supplier",
- "Sales and Purchase Return Tool",
- "Make Debit Note",
- "Cust/Supp Address",
- "Sales Invoice No",
- "Make Stock Entry",
- "Purchase Receipt No",
- "Purchase Return",
- "Sales and Purchase Return Items",
- "Return Date",
- "Cust/Supp Name",
- "Return Type",
- "Stock"
-]
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/ar-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/ar-doc.json
deleted file mode 100644
index d11ece6..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/ar-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "\u0634\u0631\u0643\u0629",
- "Cust/Supp Address": "\u0627\u0644\u0632\u0628\u0648\u0646 / \u0627\u0644\u0645\u0644\u062d\u0642 \u0627\u0644\u0639\u0646\u0648\u0627\u0646",
- "Cust/Supp Name": "\u0627\u0644\u0632\u0628\u0648\u0646 / \u0627\u0644\u0645\u0644\u062d\u0642 \u0627\u0633\u0645",
- "Customer/Supplier": "\u0627\u0644\u0639\u0645\u064a\u0644 / \u0645\u0632\u0648\u062f",
- "Delivery Note No": "\u0645\u0644\u0627\u062d\u0638\u0629 \u0644\u0627 \u062a\u0633\u0644\u064a\u0645",
- "Get Items": "\u0627\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0627\u0644\u0639\u0646\u0627\u0635\u0631",
- "Make Credit Note": "\u062c\u0639\u0644 \u0627\u0644\u0627\u0626\u062a\u0645\u0627\u0646\u064a",
- "Make Debit Note": "\u0645\u0644\u0627\u062d\u0638\u0629 \u062c\u0639\u0644 \u0627\u0644\u062e\u0635\u0645",
- "Make Excise Invoice": "\u062c\u0639\u0644 \u0627\u0644\u0641\u0627\u062a\u0648\u0631\u0629 \u0627\u0644\u0645\u0643\u0648\u0633",
- "Make Stock Entry": "\u062c\u0639\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0644\u0644\u0633\u0647\u0645",
- "Purchase Receipt No": "\u0644\u0627 \u0634\u0631\u0627\u0621 \u0627\u0633\u062a\u0644\u0627\u0645",
- "Purchase Return": "\u0634\u0631\u0627\u0621 \u0627\u0644\u0639\u0648\u062f\u0629",
- "Return Date": "\u0627\u0644\u0639\u0648\u062f\u0629 \u062a\u0627\u0631\u064a\u062e",
- "Return Type": "\u0627\u0644\u0639\u0648\u062f\u0629 \u0646\u0648\u0639",
- "Sales Invoice No": "\u0641\u0627\u062a\u0648\u0631\u0629 \u0645\u0628\u064a\u0639\u0627\u062a \u0644\u0627",
- "Sales Return": "\u0645\u0628\u064a\u0639\u0627\u062a \u0627\u0644\u0639\u0648\u062f\u0629",
- "Sales and Purchase Return Items": "\u0645\u0627\u062f\u0629 \u0639\u0627\u0626\u062f \u0627\u0644\u0645\u0628\u064a\u0639\u0627\u062a \u0648\u0627\u0644\u0645\u0634\u062a\u0631\u064a\u0627\u062a",
- "Sales and Purchase Return Tool": "\u0645\u0628\u064a\u0639\u0627\u062a \u0648\u0634\u0631\u0627\u0621 \u0623\u062f\u0627\u0629 \u0627\u0644\u0639\u0648\u062f\u0629",
- "Stock": "\u0627\u0644\u0623\u0648\u0631\u0627\u0642 \u0627\u0644\u0645\u0627\u0644\u064a\u0629"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/de-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/de-doc.json
deleted file mode 100644
index 9bd8c9a..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/de-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "Firma",
- "Cust/Supp Address": "Cust / Supp Adresse",
- "Cust/Supp Name": "Cust / Supp Namen",
- "Customer/Supplier": "Kunde / Lieferant",
- "Delivery Note No": "Lieferschein Nein",
- "Get Items": "Holen Artikel",
- "Make Credit Note": "Machen Gutschrift",
- "Make Debit Note": "Machen Lastschrift",
- "Make Excise Invoice": "Machen Excise Rechnung",
- "Make Stock Entry": "Machen Eintrag Stock",
- "Purchase Receipt No": "Kaufbeleg",
- "Purchase Return": "Kauf zur\u00fcckgeben",
- "Return Date": "Zur\u00fcck Datum",
- "Return Type": "R\u00fcckgabetyp",
- "Sales Invoice No": "Sales Invoice In",
- "Sales Return": "Umsatzrendite",
- "Sales and Purchase Return Items": "Verkauf und Kauf zur\u00fccksenden Artikel",
- "Sales and Purchase Return Tool": "Sales and Purchase Return-Tool",
- "Stock": "Lager"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/es-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/es-doc.json
deleted file mode 100644
index ac44049..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/es-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "Empresa",
- "Cust/Supp Address": "Cust / Supp Direcci\u00f3n",
- "Cust/Supp Name": "Cust / Supp Nombre",
- "Customer/Supplier": "Cliente / Proveedor",
- "Delivery Note No": "Entrega Nota No",
- "Get Items": "Obtener elementos",
- "Make Credit Note": "Hacer Nota de Cr\u00e9dito",
- "Make Debit Note": "Hacer Nota de D\u00e9bito",
- "Make Excise Invoice": "Hacer Factura Impuestos Especiales",
- "Make Stock Entry": "Hacer de la entrada",
- "Purchase Receipt No": "No recibo de compra",
- "Purchase Return": "Comprar Volver",
- "Return Date": "Fecha de regreso",
- "Return Type": "Devuelto",
- "Sales Invoice No": "Ventas factura n \u00ba",
- "Sales Return": "Ventas Retorno",
- "Sales and Purchase Return Items": "Ventas y comprar art\u00edculos de Retorno",
- "Sales and Purchase Return Tool": "Herramienta de ventas y devoluci\u00f3n de compra",
- "Stock": "Valores"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/fr-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/fr-doc.json
deleted file mode 100644
index c3fc153..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/fr-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "Entreprise",
- "Cust/Supp Address": "Cust / Supp Adresse",
- "Cust/Supp Name": "Cust / Supp Nom",
- "Customer/Supplier": "Client / Fournisseur",
- "Delivery Note No": "Remarque Aucune livraison",
- "Get Items": "Obtenir les \u00e9l\u00e9ments",
- "Make Credit Note": "Assurez note de cr\u00e9dit",
- "Make Debit Note": "Assurez note de d\u00e9bit",
- "Make Excise Invoice": "Assurez facture d'accise",
- "Make Stock Entry": "Assurez Entr\u00e9e Stock",
- "Purchase Receipt No": "Achetez un accus\u00e9 de r\u00e9ception",
- "Purchase Return": "Achat de retour",
- "Return Date": "Date de retour",
- "Return Type": "Retour Type",
- "Sales Invoice No": "Aucune facture de vente",
- "Sales Return": "Ventes de retour",
- "Sales and Purchase Return Items": "Ventes et articles de retour d'achat",
- "Sales and Purchase Return Tool": "Outil de vente et de retour d'achat",
- "Stock": "Stock"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/hi-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/hi-doc.json
deleted file mode 100644
index b407775..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/hi-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "\u0915\u0902\u092a\u0928\u0940",
- "Cust/Supp Address": "Cust / Supp \u092a\u0924\u093e",
- "Cust/Supp Name": "Cust / Supp \u0928\u093e\u092e",
- "Customer/Supplier": "\u0917\u094d\u0930\u093e\u0939\u0915 / \u0906\u092a\u0942\u0930\u094d\u0924\u093f\u0915\u0930\u094d\u0924\u093e",
- "Delivery Note No": "\u0921\u093f\u0932\u093f\u0935\u0930\u0940 \u0928\u094b\u091f",
- "Get Items": "\u0906\u0907\u091f\u092e \u092a\u093e\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f",
- "Make Credit Note": "\u0915\u094d\u0930\u0947\u0921\u093f\u091f \u0928\u094b\u091f",
- "Make Debit Note": "\u0921\u0947\u092c\u093f\u091f \u0928\u094b\u091f",
- "Make Excise Invoice": "\u0909\u0924\u094d\u092a\u093e\u0926 \u0936\u0941\u0932\u094d\u0915 \u091a\u093e\u0932\u093e\u0928",
- "Make Stock Entry": "\u0938\u094d\u091f\u0949\u0915 \u090f\u0902\u091f\u094d\u0930\u0940",
- "Purchase Receipt No": "\u0930\u0938\u0940\u0926 \u0916\u0930\u0940\u0926 \u0928\u0939\u0940\u0902",
- "Purchase Return": "\u0915\u094d\u0930\u092f \u0935\u093e\u092a\u0938\u0940",
- "Return Date": "\u0924\u093f\u0925\u093f \u0932\u094c\u091f\u0947\u0902",
- "Return Type": "\u092a\u094d\u0930\u0915\u093e\u0930 \u0932\u094c\u091f\u0947\u0902",
- "Sales Invoice No": "\u092c\u093f\u0915\u094d\u0930\u0940 \u091a\u093e\u0932\u093e\u0928 \u0928\u0939\u0940\u0902",
- "Sales Return": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0932\u094c\u091f\u0947\u0902",
- "Sales and Purchase Return Items": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0914\u0930 \u0916\u0930\u0940\u0926 \u0915\u0947 \u0930\u093f\u091f\u0930\u094d\u0928 \u0906\u0907\u091f\u092e",
- "Sales and Purchase Return Tool": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0914\u0930 \u0916\u0930\u0940\u0926 \u0915\u0947 \u0930\u093f\u091f\u0930\u094d\u0928 \u091f\u0942\u0932",
- "Stock": "\u0938\u094d\u091f\u0949\u0915"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/hr-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/hr-doc.json
deleted file mode 100644
index aa579a9..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/hr-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "Dru\u0161tvo",
- "Cust/Supp Address": "Cust / Supp Adresa",
- "Cust/Supp Name": "Cust / Supp Ime",
- "Customer/Supplier": "Kupac / Dobavlja\u010d",
- "Delivery Note No": "Dostava Napomena Ne",
- "Get Items": "Nabavite artikle",
- "Make Credit Note": "Napravite Credit Note",
- "Make Debit Note": "Napravite tere\u0107enju",
- "Make Excise Invoice": "Napravite tro\u0161arinama fakture",
- "Make Stock Entry": "Napravite Stock Entry",
- "Purchase Receipt No": "Ra\u010dun kupnje Ne",
- "Purchase Return": "Kupnja Povratak",
- "Return Date": "Povratak Datum",
- "Return Type": "Povratak Vid",
- "Sales Invoice No": "Prodaja Ra\u010dun br",
- "Sales Return": "Prodaje Povratak",
- "Sales and Purchase Return Items": "Prodaja i kupnja Povratak Stavke",
- "Sales and Purchase Return Tool": "Prodaja i kupnja Povratak Tool",
- "Stock": "Zaliha"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/nl-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/nl-doc.json
deleted file mode 100644
index fd586c1..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/nl-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "Vennootschap",
- "Cust/Supp Address": "Cust / Supp Adres",
- "Cust/Supp Name": "Cust / Supp Naam",
- "Customer/Supplier": "Klant / leverancier",
- "Delivery Note No": "Levering aantekening",
- "Get Items": "Get Items",
- "Make Credit Note": "Maak Creditnota",
- "Make Debit Note": "Maak debetnota",
- "Make Excise Invoice": "Maak Accijnzen Factuur",
- "Make Stock Entry": "Maak Stock Entry",
- "Purchase Receipt No": "Aankoopbewijs Geen",
- "Purchase Return": "Aankoop Return",
- "Return Date": "Keer terug Datum",
- "Return Type": "Terug Type",
- "Sales Invoice No": "Verkoop Factuur nr.",
- "Sales Return": "Verkoop Terug",
- "Sales and Purchase Return Items": "Verkoop en Inkoop Return Items",
- "Sales and Purchase Return Tool": "Verkoop en Inkoop Return Tool",
- "Stock": "Voorraad"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/pt-BR-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/pt-BR-doc.json
deleted file mode 100644
index f218bfa..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/pt-BR-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "Empresa",
- "Cust/Supp Address": "Endere\u00e7o do Cliente/Fornecedor",
- "Cust/Supp Name": "Nome do Cliente/Fornecedor",
- "Customer/Supplier": "Cliente / Fornecedor",
- "Delivery Note No": "N\u00ba da Guia de Remessa",
- "Get Items": "Obter itens",
- "Make Credit Note": "Fazer Nota de Cr\u00e9dito",
- "Make Debit Note": "Fazer Nota de D\u00e9bito",
- "Make Excise Invoice": "Fazer fatura de imposto",
- "Make Stock Entry": "Fazer lan\u00e7amento de estoque",
- "Purchase Receipt No": "N\u00ba do Recibo de Compra",
- "Purchase Return": "Devolu\u00e7\u00e3o de Compra",
- "Return Date": "Data de retorno",
- "Return Type": "Tipo de retorno",
- "Sales Invoice No": "N\u00ba da Nota Fiscal de Venda",
- "Sales Return": "Retorno de Vendas",
- "Sales and Purchase Return Items": "Itens de retorno de compra e venda",
- "Sales and Purchase Return Tool": "Ferramenta de retorno de compra e venda",
- "Stock": "Estoque"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/pt-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/pt-doc.json
deleted file mode 100644
index ce3685e..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/pt-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "Companhia",
- "Cust/Supp Address": "Cust / Supp Endere\u00e7o",
- "Cust/Supp Name": "Cust / Supp Nome",
- "Customer/Supplier": "Cliente / Fornecedor",
- "Delivery Note No": "Nota de Entrega N\u00e3o",
- "Get Items": "Obter itens",
- "Make Credit Note": "Fa\u00e7a Nota de Cr\u00e9dito",
- "Make Debit Note": "Fa\u00e7a Nota de D\u00e9bito",
- "Make Excise Invoice": "Fa\u00e7a fatura Excise",
- "Make Stock Entry": "Fa\u00e7a entrada de material",
- "Purchase Receipt No": "Compra recibo N\u00e3o",
- "Purchase Return": "Voltar comprar",
- "Return Date": "Data de regresso",
- "Return Type": "Tipo de retorno",
- "Sales Invoice No": "Vendas factura n",
- "Sales Return": "Vendas Retorno",
- "Sales and Purchase Return Items": "Vendas e itens de retorno de Compra",
- "Sales and Purchase Return Tool": "Ferramenta de vendas e retorno de compra",
- "Stock": "Estoque"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/sr-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/sr-doc.json
deleted file mode 100644
index 4903a9f..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/sr-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "\u041a\u043e\u043c\u043f\u0430\u043d\u0438\u0458\u0430",
- "Cust/Supp Address": "\u041a\u043e\u0440\u0438\u0441\u043d\u0438\u0447\u043a\u0430 / \u0421\u0443\u043f\u043f \u0410\u0434\u0440\u0435\u0441\u0430",
- "Cust/Supp Name": "\u041a\u043e\u0440\u0438\u0441\u043d\u0438\u0447\u043a\u0430 / \u0421\u0443\u043f\u043f \u0418\u043c\u0435",
- "Customer/Supplier": "\u041a\u043e\u0440\u0438\u0441\u043d\u0438\u0447\u043a\u0438 / \u0414\u043e\u0431\u0430\u0432\u0459\u0430\u0447",
- "Delivery Note No": "\u0418\u0441\u043f\u043e\u0440\u0443\u043a\u0430 \u041d\u0430\u043f\u043e\u043c\u0435\u043d\u0430 \u041d\u0435",
- "Get Items": "\u0413\u0435\u0442 \u0441\u0442\u0430\u0432\u043a\u0435",
- "Make Credit Note": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u041d\u043e\u0442\u0435 \u0426\u0440\u0435\u0434\u0438\u0442",
- "Make Debit Note": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u0437\u0430\u0434\u0443\u0436\u0435\u045a\u0443",
- "Make Excise Invoice": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u0430\u043a\u0446\u0438\u0437\u0430\u043c\u0430 \u0444\u0430\u043a\u0442\u0443\u0440\u0443",
- "Make Stock Entry": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u0443\u043d\u043e\u0441 \u0421\u0442\u043e\u0446\u043a",
- "Purchase Receipt No": "\u041a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u041f\u0440\u0438\u0458\u0435\u043c \u041d\u0435\u043c\u0430",
- "Purchase Return": "\u041a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u0420\u0435\u0442\u0443\u0440\u043d",
- "Return Date": "\u0420\u0435\u0442\u0443\u0440\u043d \u0414\u0430\u0442\u0435",
- "Return Type": "\u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a \u0412\u0438\u0434",
- "Sales Invoice No": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0420\u0430\u0447\u0443\u043d \u041d\u0435\u043c\u0430",
- "Sales Return": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0420\u0435\u0442\u0443\u0440\u043d",
- "Sales and Purchase Return Items": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0438 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u0438 \u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a \u041a\u0443\u043f\u043e\u0432\u0438\u043d\u0430",
- "Sales and Purchase Return Tool": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0438 \u043a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u0430\u043b\u0430\u0442\u0430 \u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a",
- "Stock": "\u0417\u0430\u043b\u0438\u0445\u0430"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/ta-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/ta-doc.json
deleted file mode 100644
index 4d1ddc3..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/ta-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "\u0ba8\u0bbf\u0bb1\u0bc1\u0bb5\u0ba9\u0bae\u0bcd",
- "Cust/Supp Address": "Cust / \u0b9a\u0baa\u0bcd \u0bae\u0bc1\u0b95\u0bb5\u0bb0\u0bbf",
- "Cust/Supp Name": "Cust / \u0b9a\u0baa\u0bcd \u0baa\u0bc6\u0baf\u0bb0\u0bcd",
- "Customer/Supplier": "\u0bb5\u0bbe\u0b9f\u0bbf\u0b95\u0bcd\u0b95\u0bc8\u0baf\u0bbe\u0bb3\u0bb0\u0bcd / \u0b9a\u0baa\u0bcd\u0bb3\u0bc8\u0baf\u0bb0\u0bcd",
- "Delivery Note No": "\u0b9f\u0bc6\u0bb2\u0bbf\u0bb5\u0bb0\u0bbf \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bc1 \u0b87\u0bb2\u0bcd\u0bb2\u0bc8",
- "Get Items": "\u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0b9f\u0bcd\u0b95\u0bb3\u0bcd \u0b95\u0bbf\u0b9f\u0bc8\u0b95\u0bcd\u0b95\u0bc1\u0bae\u0bcd",
- "Make Credit Note": "\u0b95\u0b9f\u0ba9\u0bcd \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf",
- "Make Debit Note": "\u0baa\u0bb1\u0bcd\u0bb1\u0bc1 \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf",
- "Make Excise Invoice": "\u0bae\u0ba4\u0bc1\u0bb5\u0bb0\u0bbf \u0bb5\u0bbf\u0bb2\u0bc8\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bcd \u0bb5\u0bc8\u0b95\u0bcd\u0b95",
- "Make Stock Entry": "\u0baa\u0b99\u0bcd\u0b95\u0bc1 \u0ba8\u0bc1\u0bb4\u0bc8\u0bb5\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf",
- "Purchase Receipt No": "\u0b87\u0bb2\u0bcd\u0bb2\u0bc8 \u0b9a\u0bc0\u0b9f\u0bcd\u0b9f\u0bc1 \u0bb5\u0bbe\u0b99\u0bcd\u0b95",
- "Purchase Return": "\u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0bb5\u0bbe\u0b99\u0bcd\u0b95",
- "Return Date": "\u0ba4\u0bc7\u0ba4\u0bbf \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bbf",
- "Return Type": "\u0bb5\u0b95\u0bc8 \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa",
- "Sales Invoice No": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bb5\u0bbf\u0bb2\u0bc8\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bcd \u0b87\u0bb2\u0bcd\u0bb2\u0bc8",
- "Sales Return": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 Return",
- "Sales and Purchase Return Items": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b95\u0bc6\u0bbe\u0bb3\u0bcd\u0bae\u0bc1\u0ba4\u0bb2\u0bcd \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",
- "Sales and Purchase Return Tool": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b95\u0bc6\u0bbe\u0bb3\u0bcd\u0bae\u0bc1\u0ba4\u0bb2\u0bcd \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0b95\u0bb0\u0bc1\u0bb5\u0bbf",
- "Stock": "\u0baa\u0b99\u0bcd\u0b95\u0bc1"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/th-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/th-doc.json
deleted file mode 100644
index 732dfd7..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/locale/th-doc.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "Company": "\u0e1a\u0e23\u0e34\u0e29\u0e31\u0e17",
- "Cust/Supp Address": "\u0e17\u0e35\u0e48\u0e2d\u0e22\u0e39\u0e48 cust / Supp",
- "Cust/Supp Name": "\u0e0a\u0e37\u0e48\u0e2d cust / Supp",
- "Customer/Supplier": "\u0e25\u0e39\u0e01\u0e04\u0e49\u0e32 / \u0e1c\u0e39\u0e49\u0e1c\u0e25\u0e34\u0e15",
- "Delivery Note No": "\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e2b\u0e15\u0e38\u0e08\u0e31\u0e14\u0e2a\u0e48\u0e07\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\u0e44\u0e21\u0e48\u0e21\u0e35",
- "Get Items": "\u0e23\u0e31\u0e1a\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32",
- "Make Credit Note": "\u0e43\u0e2b\u0e49\u0e08\u0e14\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e40\u0e04\u0e23\u0e14\u0e34\u0e15",
- "Make Debit Note": "\u0e43\u0e2b\u0e49\u0e08\u0e14\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e40\u0e14\u0e1a\u0e34\u0e15",
- "Make Excise Invoice": "\u0e17\u0e33\u0e43\u0e2b\u0e49\u0e43\u0e1a\u0e41\u0e08\u0e49\u0e07\u0e2b\u0e19\u0e35\u0e49\u0e2a\u0e23\u0e23\u0e1e\u0e2a\u0e32\u0e21\u0e34\u0e15",
- "Make Stock Entry": "\u0e17\u0e33\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32",
- "Purchase Receipt No": "\u0e43\u0e1a\u0e40\u0e2a\u0e23\u0e47\u0e08\u0e23\u0e31\u0e1a\u0e40\u0e07\u0e34\u0e19\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e21\u0e48\u0e21\u0e35",
- "Purchase Return": "\u0e0b\u0e37\u0e49\u0e2d\u0e01\u0e25\u0e31\u0e1a",
- "Return Date": "\u0e01\u0e25\u0e31\u0e1a\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48",
- "Return Type": "\u0e01\u0e25\u0e31\u0e1a\u0e0a\u0e19\u0e34\u0e14",
- "Sales Invoice No": "\u0e02\u0e32\u0e22\u0e43\u0e1a\u0e41\u0e08\u0e49\u0e07\u0e2b\u0e19\u0e35\u0e49\u0e44\u0e21\u0e48\u0e21\u0e35",
- "Sales Return": "\u0e02\u0e32\u0e22\u0e01\u0e25\u0e31\u0e1a",
- "Sales and Purchase Return Items": "\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e22\u0e49\u0e2d\u0e19\u0e01\u0e25\u0e31\u0e1a",
- "Sales and Purchase Return Tool": "\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e21\u0e37\u0e2d\u0e22\u0e49\u0e2d\u0e19\u0e01\u0e25\u0e31\u0e1a",
- "Stock": "\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32"
-}
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js b/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js
deleted file mode 100644
index 2dd2e71..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js
+++ /dev/null
@@ -1,229 +0,0 @@
-// ERPNext - web based ERP (http://erpnext.com)
-// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-cur_frm.add_fetch("delivery_note_no", "company", "company");
-cur_frm.add_fetch("sales_invoice_no", "company", "company");
-cur_frm.add_fetch("purchase_receipt_no", "company", "company");
-
-// Onload
-//-------------------------------
-cur_frm.cscript.onload = function(doc,dt,dn){
- if(!doc.return_date) set_multiple(dt,dn,{return_date:get_today()});
- doc.delivery_note_no = '';
- doc.purchase_receipt_no = '';
- doc.sales_invoice_no = '';
- doc.return_type ='';
- refresh_many(['delivery_note_no', 'sales_invoice_no', 'purchase_receipt_no', 'return_type']);
-}
-
-// Link field query
-//--------------------------------
-cur_frm.fields_dict.delivery_note_no.get_query = function(doc) {
- return 'SELECT DISTINCT `tabDelivery Note`.name FROM `tabDelivery Note` WHERE `tabDelivery Note`.docstatus = 1 AND `tabDelivery Note`.%(key)s LIKE "%s" ORDER BY `tabDelivery Note`.name desc LIMIT 50';
-}
-
-cur_frm.fields_dict.sales_invoice_no.get_query = function(doc) {
- return 'SELECT DISTINCT `tabSales Invoice`.name FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1 AND `tabSales Invoice`.%(key)s LIKE "%s" ORDER BY `tabSales Invoice`.name desc LIMIT 50';
-}
-
-cur_frm.fields_dict.purchase_receipt_no.get_query = function(doc) {
- return 'SELECT DISTINCT `tabPurchase Receipt`.name FROM `tabPurchase Receipt` WHERE `tabPurchase Receipt`.docstatus = 1 AND `tabPurchase Receipt`.%(key)s LIKE "%s" ORDER BY `tabPurchase Receipt`.name desc LIMIT 50';
-}
-
-// Hide/unhide based on return type
-//----------------------------------
-cur_frm.cscript.return_type = function(doc, cdt, cdn) {
- var cp = wn.control_panel;
- hide_field(['purchase_receipt_no', 'delivery_note_no', 'sales_invoice_no', 'return_details', 'get_items', 'make_excise_invoice', 'make_stock_entry', 'make_debit_note', 'make_credit_note']);
-
- if(doc.return_type == 'Sales Return') {
- unhide_field(['delivery_note_no', 'sales_invoice_no', 'get_items', 'return_details', 'make_credit_note', 'make_stock_entry']);
-
- if(cp.country == 'India') { unhide_field(['make_excise_invoice']); }
-
- } else if(doc.return_type == 'Purchase Return') {
- unhide_field(['purchase_receipt_no', 'get_items', 'return_details', 'make_debit_note', 'make_stock_entry']);
-
- if(cp.country == 'India') { unhide_field(['make_excise_invoice']);}
- }
-
- cur_frm.cscript.clear_fields(doc);
-}
-
-// Create item table
-//-------------------------------
-cur_frm.cscript.get_items = function(doc, cdt, cdn) {
- flag = 0
- if(doc.return_type == 'Sales Return') {
- if (doc.delivery_note_no && doc.sales_invoice_no) {
- msgprint("You can not enter both Delivery Note No and Sales Invoice No. Please enter any one.");
- flag = 1;
- } else if (!doc.delivery_note_no && !doc.sales_invoice_no) {
- msgprint("Please enter Delivery Note No or Sales Invoice No to proceed");
- flag = 1;
- }
- } else if (doc.return_type == 'Purchase Return' && !doc.purchase_receipt_no) {
- msgprint("Please enter Purchase Receipt No to proceed");
- flag = 1;
- }
- if (!flag)
- $c_obj(make_doclist(doc.doctype, doc.name),'pull_item_details','', function(r, rt) {
- refresh_many(['return_details', 'cust_supp', 'cust_supp_name', 'cust_supp_address']);
- });
-}
-
-// Clear fields
-//-------------------------------
-cur_frm.cscript.clear_fields = function(doc) {
- doc.purchase_receipt_no, doc.delivery_note_no, doc.sales_invoice_no = '', '', '';
- var cl = getchildren('Sales and Purchase Return Item', doc.name, 'return_details')
- if(cl.length) $c_obj(make_doclist(doc.doctype, doc.name),'clear_return_table','', function(r, rt) {refresh_field('return_details')});
- refresh_many(['delivery_note_no', 'sales_invoice_no', 'purchase_receipt_no', 'return_details']);
-}
-
-// Make Stock Entry
-//-------------------------------
-cur_frm.cscript.make_stock_entry = function(doc, cdt, cdn) {
- var cl = getchildren('Sales and Purchase Return Item', doc.name, 'return_details');
- if (!cl.length)
- msgprint("Item table can not be blank. Please click on 'Get Items'.");
- else if (!cur_frm.cscript.validate_returned_qty(cl)) {
- se = cur_frm.cscript.map_parent_fields(doc,cdt,cdn);
- cur_frm.cscript.map_child_fields(cl, se);
- loaddoc('Stock Entry', se.name);
- }
-}
-
-// Validate returned qty
-//---------------------------
-cur_frm.cscript.validate_returned_qty = function(cl) {
- flag = 0
- for(var i = 0; i<cl.length; i++){
- if(cl[i].returned_qty > cl[i].qty) {
- msgprint("Returned Qty can not be greater than qty. Please check for item: " + cl[i].item_code);
- flag = 1
- }
- }
- return flag
-}
-
-
-// map parent fields of stock entry
-//----------------------------------
-cur_frm.cscript.map_parent_fields = function(doc, cdt, cdn) {
- var se = wn.model.make_new_doc_and_get_name('Stock Entry');
- se = locals['Stock Entry'][se];
- se.posting_date = dateutil.obj_to_str(new Date());
- se.transfer_date = dateutil.obj_to_str(new Date());
- se.fiscal_year = sys_defaults.fiscal_year;
- se.purpose = doc.return_type;
- se.remarks = doc.return_type + ' of ' + (doc.delivery_note_no || doc.sales_invoice_no || doc.purchase_receipt_no);
- if(doc.return_type == 'Sales Return'){
- se.delivery_note_no = doc.delivery_note_no;
- se.sales_invoice_no = doc.sales_invoice_no;
- se.customer = doc.cust_supp_name;
- se.customer_name = doc.cust_supp_name;
- se.customer_address = doc.cust_supp_address;
- }
- else if(doc.return_type == 'Purchase Return'){
- se.purchase_receipt_no = doc.purchase_receipt_no;
- se.supplier = doc.cust_supp_name;
- se.supplier_name = doc.cust_supp_name;
- se.supplier_address = doc.cust_supp_address;
- }
- return se
-}
-
-// map child fields of stock entry
-//---------------------------------
-cur_frm.cscript.map_child_fields = function(cl, se) {
- for(var i = 0; i<cl.length; i++){
- if (cl[i].returned_qty) {
- var d1 = wn.model.add_child(se, 'Stock Entry Detail', 'mtn_details');
- d1.detail_name = cl[i].detail_name;
- d1.item_code = cl[i].item_code;
- d1.description = cl[i].description;
- d1.transfer_qty = cl[i].returned_qty;
- d1.qty = cl[i].returned_qty;
- d1.stock_uom = cl[i].uom;
- d1.uom = cl[i].uom;
- d1.conversion_factor = 1;
- d1.incoming_rate = cl[i].rate;
- d1.serial_no = cl[i].serial_no;
- d1.batch_no = cl[i].batch_no;
- }
- }
-}
-
-// Make excise voucher
-//-------------------------------
-cur_frm.cscript.make_excise_invoice = function(doc) {
- var excise = wn.model.make_new_doc_and_get_name('Journal Voucher');
- excise = locals['Journal Voucher'][excise];
- excise.voucher_type = 'Excise Voucher';
- loaddoc('Journal Voucher',excise.name);
-}
-// Make debit note
-//------------------------------
-cur_frm.cscript.make_debit_note = function(doc) {
- var doclist = make_doclist(doc.doctype, doc.name);
- $c('accounts.get_new_jv_details', {
- doclist: JSON.stringify(doclist),
- fiscal_year: sys_defaults.fiscal_year
- }, function(r, rt) {
- if(!r.exc) {
- cur_frm.cscript.make_jv(doc, 'Debit Note', r.message);
- }
- });
-}
-// Make credit note
-//------------------------------
-cur_frm.cscript.make_credit_note = function(doc) {
- var doclist = make_doclist(doc.doctype, doc.name);
- $c('accounts.get_new_jv_details', {
- doclist: JSON.stringify(doclist),
- fiscal_year: sys_defaults.fiscal_year,
- }, function(r, rt) {
- if(!r.exc) {
- cur_frm.cscript.make_jv(doc, 'Credit Note', r.message);
- }
- });
-}
-
-
-// Make JV
-//--------------------------------
-cur_frm.cscript.make_jv = function(doc, dr_or_cr, children) {
- var jv = wn.model.make_new_doc_and_get_name('Journal Voucher');
- jv = locals['Journal Voucher'][jv];
-
- jv.voucher_type = dr_or_cr;
- jv.company = sys_defaults.company;
- jv.fiscal_year = sys_defaults.fiscal_year;
- jv.is_opening = 'No';
- jv.posting_date = doc.return_date;
-
- // Add children
- if(children) {
- for(var i=0; i<children.length; i++) {
- var ch = wn.model.add_child(jv, 'Journal Voucher Detail', 'entries');
- $.extend(ch, children[i]);
- ch.balance = flt(ch.balance);
- }
- }
-
- loaddoc('Journal Voucher', jv.name);
-}
diff --git a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py b/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py
deleted file mode 100644
index f0170bb..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-import webnotes
-
-from webnotes.utils import flt
-from webnotes.model import db_exists
-from webnotes.model.doc import addchild
-from webnotes.model.bean import copy_doclist
-
-sql = webnotes.conn.sql
-
-
-class DocType :
- def __init__(self, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
-
- # Pull Item Details
- # ---------------------------
- def pull_item_details(self):
- if self.doc.return_type == 'Sales Return':
- if self.doc.delivery_note_no:
- det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.uom, t2.export_rate * t3.conversion_rate, t3.customer, t3.customer_name, t3.customer_address, t2.serial_no, t2.batch_no from `tabDelivery Note Packing Item` t1, `tabDelivery Note Item` t2, `tabDelivery Note` t3 where t1.parent = t3.name and t2.parent = t3.name and t1.parent_detail_docname = t2.name and t3.name = '%s' and t3.docstatus = 1" % self.doc.delivery_note_no)
- elif self.doc.sales_invoice_no:
- det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.stock_uom, t1.export_rate * t2.conversion_rate, t2.customer, t2.customer_name, t2.customer_address, t1.serial_no from `tabSales Invoice Item` t1, `tabSales Invoice` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.sales_invoice_no)
- elif self.doc.return_type == 'Purchase Return' and self.doc.purchase_receipt_no:
- det = sql("select t1.name, t1.item_code, t1.description, t1.received_qty, t1.uom, t1.purchase_rate, t2.supplier, t2.supplier_name, t2.supplier_address, t1.serial_no, t1.batch_no from `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.purchase_receipt_no)
-
- self.doc.cust_supp = det and det[0][6] or ''
- self.doc.cust_supp_name = det and det[0][7] or ''
- self.doc.cust_supp_address = det and det[0][8] or ''
- self.create_item_table(det)
- self.doc.save()
-
- # Create Item Table
- # -----------------------------
- def create_item_table(self, det):
- self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1)
- for i in det:
- ch = addchild(self.doc, 'return_details', 'Sales and Purchase Return Item',
- self.doclist)
- ch.detail_name = i and i[0] or ''
- ch.item_code = i and i[1] or ''
- ch.description = i and i[2] or ''
- ch.qty = i and flt(i[3]) or 0
- ch.uom = i and i[4] or ''
- ch.rate = i and flt(i[5]) or 0
- ch.serial_no = i and i[9] or ''
- ch.batch_no = (len(i) == 11) and i[10] or ''
- ch.save()
-
- # Clear return table
- # --------------------------------
- def clear_return_table(self):
- self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1)
- self.doc.save()
\ No newline at end of file
diff --git a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.txt b/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.txt
deleted file mode 100644
index 2daf6ac..0000000
--- a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.txt
+++ /dev/null
@@ -1,191 +0,0 @@
-[
- {
- "creation": "2013-01-10 16:34:29",
- "docstatus": 0,
- "modified": "2013-01-23 16:48:38",
- "modified_by": "Administrator",
- "owner": "wasim@webnotestech.com"
- },
- {
- "doctype": "DocType",
- "issingle": 1,
- "istable": 0,
- "module": "Stock",
- "name": "__common__"
- },
- {
- "doctype": "DocField",
- "name": "__common__",
- "parent": "Sales and Purchase Return Tool",
- "parentfield": "fields",
- "parenttype": "DocType",
- "permlevel": 0
- },
- {
- "create": 1,
- "doctype": "DocPerm",
- "name": "__common__",
- "parent": "Sales and Purchase Return Tool",
- "parentfield": "permissions",
- "parenttype": "DocType",
- "permlevel": 0,
- "read": 1,
- "report": 0,
- "submit": 0,
- "write": 1
- },
- {
- "doctype": "DocType",
- "name": "Sales and Purchase Return Tool"
- },
- {
- "doctype": "DocField",
- "fieldname": "return_date",
- "fieldtype": "Date",
- "label": "Return Date",
- "no_copy": 1,
- "oldfieldname": "return_date",
- "oldfieldtype": "Date",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "return_type",
- "fieldtype": "Select",
- "label": "Return Type",
- "no_copy": 1,
- "oldfieldname": "return_type",
- "oldfieldtype": "Select",
- "options": "\nSales Return\nPurchase Return",
- "reqd": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "delivery_note_no",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Delivery Note No",
- "no_copy": 1,
- "oldfieldname": "delivery_note_no",
- "oldfieldtype": "Link",
- "options": "Delivery Note",
- "reqd": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "sales_invoice_no",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Sales Invoice No",
- "options": "Sales Invoice"
- },
- {
- "doctype": "DocField",
- "fieldname": "purchase_receipt_no",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Purchase Receipt No",
- "no_copy": 1,
- "oldfieldname": "purchase_receipt_no",
- "oldfieldtype": "Link",
- "options": "Purchase Receipt"
- },
- {
- "doctype": "DocField",
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Company",
- "options": "Company",
- "print_hide": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "cust_supp",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Customer/Supplier",
- "print_hide": 1,
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "cust_supp_name",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Cust/Supp Name",
- "print_hide": 1,
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "cust_supp_address",
- "fieldtype": "Small Text",
- "hidden": 1,
- "label": "Cust/Supp Address",
- "print_hide": 1,
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "get_items",
- "fieldtype": "Button",
- "hidden": 1,
- "label": "Get Items",
- "oldfieldtype": "Button"
- },
- {
- "doctype": "DocField",
- "fieldname": "return_details",
- "fieldtype": "Table",
- "hidden": 1,
- "label": "Sales and Purchase Return Items",
- "no_copy": 1,
- "oldfieldname": "return_details",
- "oldfieldtype": "Table",
- "options": "Sales and Purchase Return Item",
- "read_only": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "make_stock_entry",
- "fieldtype": "Button",
- "hidden": 1,
- "label": "Make Stock Entry",
- "oldfieldtype": "Button"
- },
- {
- "doctype": "DocField",
- "fieldname": "make_excise_invoice",
- "fieldtype": "Button",
- "hidden": 1,
- "label": "Make Excise Invoice",
- "oldfieldtype": "Button"
- },
- {
- "doctype": "DocField",
- "fieldname": "make_credit_note",
- "fieldtype": "Button",
- "hidden": 1,
- "label": "Make Credit Note",
- "oldfieldtype": "Button"
- },
- {
- "doctype": "DocField",
- "fieldname": "make_debit_note",
- "fieldtype": "Button",
- "hidden": 1,
- "label": "Make Debit Note",
- "oldfieldtype": "Button"
- },
- {
- "amend": 0,
- "cancel": 0,
- "doctype": "DocPerm",
- "role": "Material User"
- },
- {
- "doctype": "DocPerm",
- "role": "Accounts User"
- }
-]
\ No newline at end of file
diff --git a/stock/doctype/sales_bom_item/sales_bom_item.txt b/stock/doctype/sales_bom_item/sales_bom_item.txt
index 0a77211..98285af 100644
--- a/stock/doctype/sales_bom_item/sales_bom_item.txt
+++ b/stock/doctype/sales_bom_item/sales_bom_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:29",
+ "creation": "2013-02-22 01:28:03",
"docstatus": 0,
- "modified": "2013-01-23 16:56:21",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -50,6 +50,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
+ "print_width": "300px",
"width": "300px"
},
{
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index 55a86a3..447f503 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -18,8 +18,77 @@
wn.provide("erpnext.stock");
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
+ onload: function() {
+ this.set_default_account();
+ },
+
+ set_default_account: function() {
+ var me = this;
+
+ if (sys_defaults.auto_inventory_accounting && !this.frm.doc.expense_adjustment_account) {
+ if (this.frm.doc.purpose == "Sales Return")
+ account_for = "stock_delivered_but_not_billed";
+ else if (this.frm.doc.purpose == "Purchase Return")
+ account_for = "stock_received_but_not_billed";
+ else account_for = "stock_adjustment_account";
+
+ this.frm.call({
+ method: "controllers.accounts_controller.get_default_account",
+ args: {
+ "account_for": account_for,
+ "company": this.frm.doc.company
+ },
+ callback: function(r) {
+ if (!r.exc) me.frm.set_value("expense_adjustment_account", r.message);
+ }
+ });
+ }
+ },
+
+ setup: function() {
+ var me = this;
+
+ this.frm.fields_dict.delivery_note_no.get_query = function() {
+ return { query: "stock.doctype.stock_entry.stock_entry.query_sales_return_doc" };
+ };
+
+ this.frm.fields_dict.sales_invoice_no.get_query =
+ this.frm.fields_dict.delivery_note_no.get_query;
+
+ this.frm.fields_dict.purchase_receipt_no.get_query = function() {
+ return { query: "stock.doctype.stock_entry.stock_entry.query_purchase_return_doc" };
+ };
+
+ this.frm.fields_dict.mtn_details.grid.get_field('item_code').get_query = function() {
+ if(in_list(["Sales Return", "Purchase Return"], me.frm.doc.purpose) &&
+ me.get_doctype_docname()) {
+ return {
+ query: "stock.doctype.stock_entry.stock_entry.query_return_item",
+ filters: {
+ purpose: me.frm.doc.purpose,
+ delivery_note_no: me.frm.doc.delivery_note_no,
+ sales_invoice_no: me.frm.doc.sales_invoice_no,
+ purchase_receipt_no: me.frm.doc.purchase_receipt_no
+ }
+ };
+ } else {
+ return erpnext.queries.item({is_stock_item: "Yes"});
+ }
+ };
+
+ if (sys_defaults.auto_inventory_accounting) {
+ this.frm.add_fetch("company", "expense_adjustment_account", "stock_adjustment_account");
+
+ this.frm.fields_dict["expense_adjustment_account"].get_query = function() {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": { "company": me.frm.doc.company }
+ }
+ }
+ }
+ },
+
onload_post_render: function() {
- this._super();
if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no)
&& !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) {
// if production order / bom is mentioned, get items
@@ -28,12 +97,25 @@
},
refresh: function() {
- this._super();
+ var me = this;
+ erpnext.hide_naming_series();
this.toggle_related_fields(this.frm.doc);
this.toggle_enable_bom();
if (this.frm.doc.docstatus==1) {
this.show_stock_ledger();
}
+
+ if(this.frm.doc.docstatus === 1 &&
+ wn.boot.profile.can_create.indexOf("Journal Voucher")!==-1) {
+ if(this.frm.doc.purpose === "Sales Return") {
+ this.frm.add_custom_button("Make Credit Note", function() { me.make_return_jv(); });
+ this.add_excise_button();
+ } else if(this.frm.doc.purpose === "Purchase Return") {
+ this.frm.add_custom_button("Make Debit Note", function() { me.make_return_jv(); });
+ this.add_excise_button();
+ }
+ }
+
},
on_submit: function() {
@@ -81,6 +163,68 @@
toggle_enable_bom: function() {
this.frm.toggle_enable("bom_no", !this.frm.doc.production_order);
},
+
+ get_doctype_docname: function() {
+ if(this.frm.doc.purpose === "Sales Return") {
+ if(this.frm.doc.delivery_note_no && this.frm.doc.sales_invoice_no) {
+ // both specified
+ msgprint(wn._("You can not enter both Delivery Note No and Sales Invoice No. \
+ Please enter any one."));
+
+ } else if(!(this.frm.doc.delivery_note_no || this.frm.doc.sales_invoice_no)) {
+ // none specified
+ msgprint(wn._("Please enter Delivery Note No or Sales Invoice No to proceed"));
+
+ } else if(this.frm.doc.delivery_note_no) {
+ return {doctype: "Delivery Note", docname: this.frm.doc.delivery_note_no};
+
+ } else if(this.frm.doc.sales_invoice_no) {
+ return {doctype: "Sales Invoice", docname: this.frm.doc.sales_invoice_no};
+
+ }
+ } else if(this.frm.doc.purpose === "Purchase Return") {
+ if(this.frm.doc.purchase_receipt_no) {
+ return {doctype: "Purchase Receipt", docname: this.frm.doc.purchase_receipt_no};
+
+ } else {
+ // not specified
+ msgprint(wn._("Please enter Purchase Receipt No to proceed"));
+
+ }
+ }
+ },
+
+ add_excise_button: function() {
+ if(wn.boot.control_panel.country === "India")
+ this.frm.add_custom_button("Make Excise Invoice", function() {
+ var excise = wn.model.make_new_doc_and_get_name('Journal Voucher');
+ excise = locals['Journal Voucher'][excise];
+ excise.voucher_type = 'Excise Voucher';
+ loaddoc('Journal Voucher', excise.name);
+ });
+ },
+
+ make_return_jv: function() {
+ this.frm.call({
+ method: "make_return_jv",
+ args: {
+ stock_entry: this.frm.doc.name
+ },
+ callback: function(r) {
+ if(!r.exc) {
+ var jv_name = wn.model.make_new_doc_and_get_name('Journal Voucher');
+ var jv = locals["Journal Voucher"][jv_name];
+ $.extend(jv, r.message[0]);
+ $.each(r.message.slice(1), function(i, jvd) {
+ var child = wn.model.add_child(jv, "Journal Voucher Detail", "entries");
+ $.extend(child, jvd);
+ });
+ loaddoc("Journal Voucher", jv_name);
+ }
+
+ }
+ });
+ },
});
@@ -141,15 +285,6 @@
cur_frm.cscript.toggle_related_fields(doc, cdt, cdn);
}
-// item code - only if quantity present in source warehosue
-var fld = cur_frm.fields_dict['mtn_details'].grid.get_field('item_code');
-fld.query_description = "If Source Warehouse is selected, items with existing stock \
- for that warehouse will be selected";
-
-fld.get_query = function() {
- return erpnext.queries.item({is_stock_item: "Yes"});
-}
-
// copy over source and target warehouses
cur_frm.fields_dict['mtn_details'].grid.onrowadd = function(doc, cdt, cdn){
var d = locals[cdt][cdn];
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 278c283..f54ce60 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -26,24 +26,27 @@
from stock.stock_ledger import get_previous_sle
import json
-
sql = webnotes.conn.sql
-
-from utilities.transaction_base import TransactionBase
-class DocType(TransactionBase):
+class NotUpdateStockError(webnotes.ValidationError): pass
+class StockOverReturnError(webnotes.ValidationError): pass
+
+from controllers.stock_controller import StockController
+
+class DocType(StockController):
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
self.fname = 'mtn_details'
def validate(self):
+ self.validate_posting_time()
self.validate_purpose()
-
self.validate_serial_nos()
pro_obj = self.doc.production_order and \
get_obj('Production Order', self.doc.production_order) or None
+ self.validate_item()
self.validate_warehouse(pro_obj)
self.validate_production_order(pro_obj)
self.get_stock_and_rate()
@@ -51,20 +54,19 @@
self.validate_bom()
self.validate_finished_goods()
self.validate_return_reference_doc()
-
self.validate_with_material_request()
def on_submit(self):
self.update_serial_no(1)
self.update_stock_ledger(0)
- # update Production Order
self.update_production_order(1)
+ self.make_gl_entries()
def on_cancel(self):
self.update_serial_no(0)
self.update_stock_ledger(1)
- # update Production Order
self.update_production_order(0)
+ self.make_gl_entries()
def validate_purpose(self):
valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer",
@@ -78,6 +80,12 @@
sl_obj.scrub_serial_nos(self)
sl_obj.validate_serial_no(self, 'mtn_details')
+ def validate_item(self):
+ for item in self.doclist.get({"parentfield": "mtn_details"}):
+ if item.item_code not in self.stock_items:
+ msgprint(_("""Only Stock Items are allowed for Stock Entry"""),
+ raise_exception=True)
+
def validate_warehouse(self, pro_obj):
"""perform various (sometimes conditional) validations on warehouse"""
@@ -159,6 +167,34 @@
elif self.doc.purpose != "Material Transfer":
self.doc.production_order = None
+ def make_gl_entries(self):
+ if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
+ return
+
+ if not self.doc.expense_adjustment_account:
+ webnotes.msgprint(_("Please enter Expense/Adjustment Account"), raise_exception=1)
+
+ from accounts.general_ledger import make_gl_entries
+
+ cost_center = "Auto Inventory Accounting - %s" % (self.company_abbr,)
+ total_valuation_amount = self.get_total_valuation_amount()
+
+ gl_entries = self.get_gl_entries_for_stock(self.doc.expense_adjustment_account,
+ total_valuation_amount, cost_center=cost_center)
+ if gl_entries:
+ make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2)
+
+ def get_total_valuation_amount(self):
+ total_valuation_amount = 0
+ for item in self.doclist.get({"parentfield": "mtn_details"}):
+ if item.t_warehouse and not item.s_warehouse:
+ total_valuation_amount += flt(item.incoming_rate) * flt(item.transfer_qty)
+
+ if item.s_warehouse and not item.t_warehouse:
+ total_valuation_amount -= flt(item.incoming_rate) * flt(item.transfer_qty)
+
+ return total_valuation_amount
+
def get_stock_and_rate(self):
"""get stock and incoming rate on posting date"""
for d in getlist(self.doclist, 'mtn_details'):
@@ -229,26 +265,55 @@
or update the Quantity manually."), raise_exception=1)
def validate_return_reference_doc(self):
- """ validate item with reference doc"""
- ref_doctype = ref_docname = ""
- if self.doc.purpose == "Sales Return" and \
- (self.doc.delivery_note_no or self.doc.sales_invoice_no):
- ref_doctype = self.doc.delivery_note_no and "Delivery Note" or "Sales Invoice"
- ref_docname = self.doc.delivery_note_no or self.doc.sales_invoice_no
- elif self.doc.purpose == "Purchase Return" and self.doc.purchase_receipt_no:
- ref_doctype = "Purchase Receipt"
- ref_docname = self.doc.purchase_receipt_no
+ """validate item with reference doc"""
+ ref = get_return_doclist_and_details(self.doc.fields)
+
+ if ref.doclist:
+ # validate docstatus
+ if ref.doclist[0].docstatus != 1:
+ webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": '
+ + _("Status should be Submitted"), raise_exception=webnotes.InvalidStatusError)
- if ref_doctype and ref_docname:
+ # update stock check
+ if ref.doclist[0].doctype == "Sales Invoice" and (cint(ref.doclist[0].is_pos) != 1 \
+ or cint(ref.doclist[0].update_stock) != 1):
+ webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": '
+ + _("Is POS and Update Stock should be checked."),
+ raise_exception=NotUpdateStockError)
+
+ # posting date check
+ ref_posting_datetime = "%s %s" % (cstr(ref.doclist[0].posting_date),
+ cstr(ref.doclist[0].posting_time) or "00:00:00")
+ this_posting_datetime = "%s %s" % (cstr(self.doc.posting_date),
+ cstr(self.doc.posting_time))
+ if this_posting_datetime < ref_posting_datetime:
+ from webnotes.utils.dateutils import datetime_in_user_format
+ webnotes.msgprint(_("Posting Date Time cannot be before")
+ + ": " + datetime_in_user_format(ref_posting_datetime),
+ raise_exception=True)
+
+ stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields)
+ already_returned_item_qty = self.get_already_returned_item_qty(ref.fieldname)
+
for item in self.doclist.get({"parentfield": "mtn_details"}):
- ref_exists = webnotes.conn.sql("""select name from `tab%s`
- where parent = %s and item_code = %s and docstatus=1""" %
- (ref_doctype + " Item", '%s', '%s'), (ref_docname, item.item_code))
-
- if not ref_exists:
- msgprint(_("Item: '") + item.item_code + _("' does not exists in ") +
- ref_doctype + ": " + ref_docname, raise_exception=1)
-
+ # validate if item exists in the ref doclist and that it is a stock item
+ if item.item_code not in stock_items:
+ msgprint(_("Item") + ': "' + item.item_code + _("\" does not exist in ") +
+ ref.doclist[0].doctype + ": " + ref.doclist[0].name,
+ raise_exception=webnotes.DoesNotExistError)
+
+ # validate quantity <= ref item's qty - qty already returned
+ ref_item = ref.doclist.getone({"item_code": item.item_code})
+ returnable_qty = ref_item.qty - flt(already_returned_item_qty.get(item.item_code))
+ self.validate_value("transfer_qty", "<=", returnable_qty, item,
+ raise_exception=StockOverReturnError)
+
+ def get_already_returned_item_qty(self, ref_fieldname):
+ return dict(webnotes.conn.sql("""select item_code, sum(transfer_qty) as qty
+ from `tabStock Entry Detail` where parent in (
+ select name from `tabStock Entry` where `%s`=%s and docstatus=1)
+ group by item_code""" % (ref_fieldname, "%s"), (self.doc.fields.get(ref_fieldname),)))
+
def update_serial_no(self, is_submit):
"""Create / Update Serial No"""
from stock.utils import get_valid_serial_nos
@@ -280,6 +345,7 @@
self.add_to_values(d, cstr(d.s_warehouse), -flt(d.transfer_qty), is_cancelled)
if cstr(d.t_warehouse):
self.add_to_values(d, cstr(d.t_warehouse), flt(d.transfer_qty), is_cancelled)
+
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values,
self.doc.amended_from and 'Yes' or 'No')
@@ -593,10 +659,270 @@
+ " " + _("Row #") + (" %d %s " % (mreq_item.idx, _("of")))
+ _("Material Request") + (" - %s" % item.material_request),
raise_exception=webnotes.MappingMismatchError)
-
+
@webnotes.whitelist()
def get_production_order_details(production_order):
result = webnotes.conn.sql("""select bom_no,
ifnull(qty, 0) - ifnull(produced_qty, 0) as fg_completed_qty, use_multi_level_bom
from `tabProduction Order` where name = %s""", production_order, as_dict=1)
- return result and result[0] or {}
\ No newline at end of file
+ return result and result[0] or {}
+
+def query_sales_return_doc(doctype, txt, searchfield, start, page_len, filters):
+ conditions = ""
+ if doctype == "Sales Invoice":
+ conditions = "and is_pos=1 and update_stock=1"
+
+ return webnotes.conn.sql("""select name, customer, customer_name
+ from `tab%s` where docstatus = 1
+ and (`%s` like %%(txt)s or `customer` like %%(txt)s) %s
+ order by name, customer, customer_name
+ limit %s""" % (doctype, searchfield, conditions, "%(start)s, %(page_len)s"),
+ {"txt": "%%%s%%" % txt, "start": start, "page_len": page_len}, as_list=True)
+
+def query_purchase_return_doc(doctype, txt, searchfield, start, page_len, filters):
+ return webnotes.conn.sql("""select name, supplier, supplier_name
+ from `tab%s` where docstatus = 1
+ and (`%s` like %%(txt)s or `supplier` like %%(txt)s)
+ order by name, supplier, supplier_name
+ limit %s""" % (doctype, searchfield, "%(start)s, %(page_len)s"),
+ {"txt": "%%%s%%" % txt, "start": start, "page_len": page_len}, as_list=True)
+
+def query_return_item(doctype, txt, searchfield, start, page_len, filters):
+ txt = txt.replace("%", "")
+
+ ref = get_return_doclist_and_details(filters)
+
+ stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields)
+
+ result = []
+ for item in ref.doclist.get({"parentfield": ["in", ref.parentfields]}):
+ if item.item_code in stock_items:
+ item.item_name = cstr(item.item_name)
+ item.description = cstr(item.description)
+ if (txt in item.item_code) or (txt in item.item_name) or (txt in item.description):
+ val = [
+ item.item_code,
+ (len(item.item_name) > 40) and (item.item_name[:40] + "...") or item.item_name,
+ (len(item.description) > 40) and (item.description[:40] + "...") or \
+ item.description
+ ]
+ if val not in result:
+ result.append(val)
+
+ return result[start:start+page_len]
+
+def get_stock_items_for_return(ref_doclist, parentfields):
+ """return item codes filtered from doclist, which are stock items"""
+ if isinstance(parentfields, basestring):
+ parentfields = [parentfields]
+
+ all_items = list(set([d.item_code for d in
+ ref_doclist.get({"parentfield": ["in", parentfields]})]))
+ stock_items = webnotes.conn.sql_list("""select name from `tabItem`
+ where is_stock_item='Yes' and name in (%s)""" % (", ".join(["%s"] * len(all_items))),
+ tuple(all_items))
+
+ return stock_items
+
+def get_return_doclist_and_details(args):
+ ref = webnotes._dict()
+
+ # get ref_doclist
+ if args["purpose"] in return_map:
+ for fieldname, val in return_map[args["purpose"]].items():
+ if args.get(fieldname):
+ ref.fieldname = fieldname
+ ref.doclist = webnotes.get_doclist(val[0], args[fieldname])
+ ref.parentfields = val[1]
+ break
+
+ return ref
+
+return_map = {
+ "Sales Return": {
+ # [Ref DocType, [Item tables' parentfields]]
+ "delivery_note_no": ["Delivery Note", ["delivery_note_details", "packing_details"]],
+ "sales_invoice_no": ["Sales Invoice", ["entries", "packing_details"]]
+ },
+ "Purchase Return": {
+ "purchase_receipt_no": ["Purchase Receipt", ["purchase_receipt_details"]]
+ }
+}
+
+@webnotes.whitelist()
+def make_return_jv(stock_entry):
+ se = webnotes.bean("Stock Entry", stock_entry)
+ if not se.doc.purpose in ["Sales Return", "Purchase Return"]:
+ return
+
+ ref = get_return_doclist_and_details(se.doc.fields)
+
+ if ref.doclist[0].doctype == "Delivery Note":
+ result = make_return_jv_from_delivery_note(se, ref)
+ elif ref.doclist[0].doctype == "Sales Invoice":
+ result = make_return_jv_from_sales_invoice(se, ref)
+ elif ref.doclist[0].doctype == "Purchase Receipt":
+ result = make_return_jv_from_purchase_receipt(se, ref)
+
+ # create jv doclist and fetch balance for each unique row item
+ jv_list = [{
+ "__islocal": 1,
+ "doctype": "Journal Voucher",
+ "posting_date": se.doc.posting_date,
+ "voucher_type": se.doc.purpose == "Sales Return" and "Credit Note" or "Debit Note",
+ "fiscal_year": se.doc.fiscal_year,
+ "company": se.doc.company
+ }]
+
+ from accounts.utils import get_balance_on
+ for r in result:
+ if not r.get("account"):
+ print result
+ jv_list.append({
+ "__islocal": 1,
+ "doctype": "Journal Voucher Detail",
+ "parentfield": "entries",
+ "account": r.get("account"),
+ "against_invoice": r.get("against_invoice"),
+ "against_voucher": r.get("against_voucher"),
+ "balance": get_balance_on(r.get("account"), se.doc.posting_date)
+ })
+
+ return jv_list
+
+def make_return_jv_from_sales_invoice(se, ref):
+ # customer account entry
+ parent = {
+ "account": ref.doclist[0].debit_to,
+ "against_invoice": ref.doclist[0].name,
+ }
+
+ # income account entries
+ children = []
+ for se_item in se.doclist.get({"parentfield": "mtn_details"}):
+ # find item in ref.doclist
+ ref_item = ref.doclist.getone({"item_code": se_item.item_code})
+
+ account = get_sales_account_from_item(ref.doclist, ref_item)
+
+ if account not in children:
+ children.append(account)
+
+ return [parent] + [{"account": account} for account in children]
+
+def get_sales_account_from_item(doclist, ref_item):
+ account = None
+ if not ref_item.income_account:
+ if ref_item.parent_item:
+ parent_item = doclist.getone({"item_code": ref_item.parent_item})
+ account = parent_item.income_account
+ else:
+ account = ref_item.income_account
+
+ return account
+
+def make_return_jv_from_delivery_note(se, ref):
+ invoices_against_delivery = get_invoice_list("Sales Invoice Item", "delivery_note",
+ ref.doclist[0].name)
+
+ if not invoices_against_delivery:
+ sales_orders_against_delivery = [d.prevdoc_docname for d in
+ ref.doclist.get({"prevdoc_doctype": "Sales Order"}) if d.prevdoc_docname]
+
+ if sales_orders_against_delivery:
+ invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order",
+ sales_orders_against_delivery)
+
+ if not invoices_against_delivery:
+ return []
+
+ packing_item_parent_map = dict([[d.item_code, d.parent_item] for d in ref.doclist.get(
+ {"parentfield": ref.parentfields[1]})])
+
+ parent = {}
+ children = []
+
+ for se_item in se.doclist.get({"parentfield": "mtn_details"}):
+ for sales_invoice in invoices_against_delivery:
+ si = webnotes.bean("Sales Invoice", sales_invoice)
+
+ if se_item.item_code in packing_item_parent_map:
+ ref_item = si.doclist.get({"item_code": packing_item_parent_map[se_item.item_code]})
+ else:
+ ref_item = si.doclist.get({"item_code": se_item.item_code})
+
+ if not ref_item:
+ continue
+
+ ref_item = ref_item[0]
+
+ account = get_sales_account_from_item(si.doclist, ref_item)
+
+ if account not in children:
+ children.append(account)
+
+ if not parent:
+ parent = {"account": si.doc.debit_to}
+
+ break
+
+ if len(invoices_against_delivery) == 1:
+ parent["against_invoice"] = invoices_against_delivery[0]
+
+ result = [parent] + [{"account": account} for account in children]
+
+ return result
+
+def get_invoice_list(doctype, link_field, value):
+ if isinstance(value, basestring):
+ value = [value]
+
+ return webnotes.conn.sql_list("""select distinct parent from `tab%s`
+ where docstatus = 1 and `%s` in (%s)""" % (doctype, link_field,
+ ", ".join(["%s"]*len(value))), tuple(value))
+
+def make_return_jv_from_purchase_receipt(se, ref):
+ invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_receipt",
+ ref.doclist[0].name)
+
+ if not invoice_against_receipt:
+ purchase_orders_against_receipt = [d.prevdoc_docname for d in
+ ref.doclist.get({"prevdoc_doctype": "Purchase Order"}) if d.prevdoc_docname]
+
+ if purchase_orders_against_receipt:
+ invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_order",
+ purchase_orders_against_receipt)
+
+ if not invoice_against_receipt:
+ return []
+
+ parent = {}
+ children = []
+
+ for se_item in se.doclist.get({"parentfield": "mtn_details"}):
+ for purchase_invoice in invoice_against_receipt:
+ pi = webnotes.bean("Purchase Invoice", purchase_invoice)
+ ref_item = pi.doclist.get({"item_code": se_item.item_code})
+
+ if not ref_item:
+ continue
+
+ ref_item = ref_item[0]
+
+ account = ref_item.expense_head
+
+ if account not in children:
+ children.append(account)
+
+ if not parent:
+ parent = {"account": pi.doc.credit_to}
+
+ break
+
+ if len(invoice_against_receipt) == 1:
+ parent["against_voucher"] = invoice_against_receipt[0]
+
+ result = [parent] + [{"account": account} for account in children]
+
+ return result
+
diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt
index 2554455..df5b613 100644
--- a/stock/doctype/stock_entry/stock_entry.txt
+++ b/stock/doctype/stock_entry/stock_entry.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-23 19:57:20",
+ "creation": "2013-03-11 12:34:40",
"docstatus": 0,
- "modified": "2013-01-28 17:59:20",
+ "modified": "2013-03-19 17:48:29",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -60,6 +60,7 @@
"fieldtype": "Column Break",
"oldfieldtype": "Column Break",
"print_width": "50%",
+ "read_only": 0,
"width": "50%"
},
{
@@ -76,6 +77,7 @@
"oldfieldtype": "Select",
"options": "\nSTE",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0
@@ -95,185 +97,12 @@
"oldfieldtype": "Select",
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nManufacture/Repack\nSubcontract\nSales Return\nPurchase Return",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0
},
{
- "doctype": "DocField",
- "fieldname": "col2",
- "fieldtype": "Column Break",
- "oldfieldtype": "Column Break",
- "print_width": "50%",
- "width": "50%"
- },
- {
- "allow_on_submit": 0,
- "default": "Today",
- "description": "The date at which current entry will get or has actually executed.",
- "doctype": "DocField",
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "label": "Posting Date",
- "no_copy": 1,
- "oldfieldname": "posting_date",
- "oldfieldtype": "Date",
- "print_hide": 1,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1
- },
- {
- "allow_on_submit": 0,
- "doctype": "DocField",
- "fieldname": "posting_time",
- "fieldtype": "Time",
- "hidden": 0,
- "in_filter": 0,
- "label": "Posting Time",
- "no_copy": 1,
- "oldfieldname": "posting_time",
- "oldfieldtype": "Time",
- "print_hide": 1,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "items_section",
- "fieldtype": "Section Break",
- "label": "Items",
- "oldfieldtype": "Section Break"
- },
- {
- "allow_on_submit": 0,
- "doctype": "DocField",
- "fieldname": "from_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Default Source Warehouse",
- "no_copy": 1,
- "oldfieldname": "from_warehouse",
- "oldfieldtype": "Link",
- "options": "Warehouse",
- "print_hide": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "cb0",
- "fieldtype": "Column Break"
- },
- {
- "allow_on_submit": 0,
- "doctype": "DocField",
- "fieldname": "to_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Default Target Warehouse",
- "no_copy": 1,
- "oldfieldname": "to_warehouse",
- "oldfieldtype": "Link",
- "options": "Warehouse",
- "print_hide": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0
- },
- {
- "doctype": "DocField",
- "fieldname": "sb0",
- "fieldtype": "Section Break",
- "options": "Simple"
- },
- {
- "allow_on_submit": 0,
- "doctype": "DocField",
- "fieldname": "mtn_details",
- "fieldtype": "Table",
- "hidden": 0,
- "in_filter": 0,
- "label": "MTN Details",
- "no_copy": 0,
- "oldfieldname": "mtn_details",
- "oldfieldtype": "Table",
- "options": "Stock Entry Detail",
- "print_hide": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0
- },
- {
- "description": "Get valuation rate and available stock at source/target warehouse on mentioned posting date-time. If serialized item, please press this button after entering serial nos.",
- "doctype": "DocField",
- "fieldname": "get_stock_and_rate",
- "fieldtype": "Button",
- "label": "Get Stock and Rate",
- "oldfieldtype": "Button",
- "options": "get_stock_and_rate",
- "print_hide": 1
- },
- {
- "doctype": "DocField",
- "fieldname": "sb1",
- "fieldtype": "Section Break",
- "label": "Reference"
- },
- {
- "allow_on_submit": 0,
- "depends_on": "eval:inList([\"Material Transfer\", \"Manufacture/Repack\"], doc.purpose)",
- "doctype": "DocField",
- "fieldname": "production_order",
- "fieldtype": "Link",
- "hidden": 1,
- "in_filter": 1,
- "label": "Production Order",
- "no_copy": 0,
- "oldfieldname": "production_order",
- "oldfieldtype": "Link",
- "options": "Production Order",
- "print_hide": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1
- },
- {
- "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
- "doctype": "DocField",
- "fieldname": "bom_no",
- "fieldtype": "Link",
- "label": "BOM No",
- "options": "BOM"
- },
- {
- "allow_on_submit": 0,
- "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
- "description": "As per Stock UOM",
- "doctype": "DocField",
- "fieldname": "fg_completed_qty",
- "fieldtype": "Float",
- "hidden": 0,
- "in_filter": 0,
- "label": "Manufacturing Quantity",
- "no_copy": 0,
- "oldfieldname": "fg_completed_qty",
- "oldfieldtype": "Currency",
- "print_hide": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0
- },
- {
"allow_on_submit": 0,
"depends_on": "eval:doc.purpose==\"Sales Return\"",
"doctype": "DocField",
@@ -292,6 +121,17 @@
"search_index": 1
},
{
+ "depends_on": "eval:doc.purpose==\"Sales Return\"",
+ "doctype": "DocField",
+ "fieldname": "sales_invoice_no",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Sales Invoice No",
+ "no_copy": 1,
+ "options": "Sales Invoice",
+ "print_hide": 1
+ },
+ {
"allow_on_submit": 0,
"depends_on": "eval:doc.purpose==\"Purchase Return\"",
"doctype": "DocField",
@@ -311,8 +151,206 @@
},
{
"doctype": "DocField",
+ "fieldname": "col2",
+ "fieldtype": "Column Break",
+ "oldfieldtype": "Column Break",
+ "print_width": "50%",
+ "read_only": 0,
+ "width": "50%"
+ },
+ {
+ "allow_on_submit": 0,
+ "default": "Today",
+ "description": "The date at which current entry will get or has actually executed.",
+ "doctype": "DocField",
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "Posting Date",
+ "no_copy": 1,
+ "oldfieldname": "posting_date",
+ "oldfieldtype": "Date",
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "allow_on_submit": 0,
+ "doctype": "DocField",
+ "fieldname": "posting_time",
+ "fieldtype": "Time",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Posting Time",
+ "no_copy": 1,
+ "oldfieldname": "posting_time",
+ "oldfieldtype": "Time",
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0
+ },
+ {
+ "depends_on": "eval:sys_defaults.auto_inventory_accounting",
+ "doctype": "DocField",
+ "fieldname": "expense_adjustment_account",
+ "fieldtype": "Link",
+ "label": "Expense/Adjustment Account",
+ "options": "Account"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "items_section",
+ "fieldtype": "Section Break",
+ "label": "Items",
+ "oldfieldtype": "Section Break",
+ "read_only": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "doctype": "DocField",
+ "fieldname": "from_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Default Source Warehouse",
+ "no_copy": 1,
+ "oldfieldname": "from_warehouse",
+ "oldfieldtype": "Link",
+ "options": "Warehouse",
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "cb0",
+ "fieldtype": "Column Break",
+ "read_only": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "doctype": "DocField",
+ "fieldname": "to_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Default Target Warehouse",
+ "no_copy": 1,
+ "oldfieldname": "to_warehouse",
+ "oldfieldtype": "Link",
+ "options": "Warehouse",
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "sb0",
+ "fieldtype": "Section Break",
+ "options": "Simple",
+ "read_only": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "doctype": "DocField",
+ "fieldname": "mtn_details",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "MTN Details",
+ "no_copy": 0,
+ "oldfieldname": "mtn_details",
+ "oldfieldtype": "Table",
+ "options": "Stock Entry Detail",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0
+ },
+ {
+ "description": "Get valuation rate and available stock at source/target warehouse on mentioned posting date-time. If serialized item, please press this button after entering serial nos.",
+ "doctype": "DocField",
+ "fieldname": "get_stock_and_rate",
+ "fieldtype": "Button",
+ "label": "Get Stock and Rate",
+ "oldfieldtype": "Button",
+ "options": "get_stock_and_rate",
+ "print_hide": 1,
+ "read_only": 0
+ },
+ {
+ "depends_on": "eval:(doc.purpose!==\"Sales Return\" || doc.purpose!==\"Purchase Return\")",
+ "doctype": "DocField",
+ "fieldname": "sb1",
+ "fieldtype": "Section Break",
+ "label": "Reference",
+ "read_only": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "depends_on": "eval:inList([\"Material Transfer\", \"Manufacture/Repack\"], doc.purpose)",
+ "doctype": "DocField",
+ "fieldname": "production_order",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "in_filter": 1,
+ "label": "Production Order",
+ "no_copy": 0,
+ "oldfieldname": "production_order",
+ "oldfieldtype": "Link",
+ "options": "Production Order",
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1
+ },
+ {
+ "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
+ "doctype": "DocField",
+ "fieldname": "bom_no",
+ "fieldtype": "Link",
+ "label": "BOM No",
+ "options": "BOM",
+ "read_only": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
+ "description": "As per Stock UOM",
+ "doctype": "DocField",
+ "fieldname": "fg_completed_qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Manufacturing Quantity",
+ "no_copy": 0,
+ "oldfieldname": "fg_completed_qty",
+ "oldfieldtype": "Currency",
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0
+ },
+ {
+ "doctype": "DocField",
"fieldname": "cb1",
- "fieldtype": "Column Break"
+ "fieldtype": "Column Break",
+ "read_only": 0
},
{
"default": "1",
@@ -321,7 +359,8 @@
"doctype": "DocField",
"fieldname": "use_multi_level_bom",
"fieldtype": "Check",
- "label": "Use Multi-Level BOM"
+ "label": "Use Multi-Level BOM",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -335,27 +374,18 @@
"no_copy": 0,
"oldfieldtype": "Button",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
},
{
- "depends_on": "eval:doc.purpose==\"Sales Return\"",
- "doctype": "DocField",
- "fieldname": "sales_invoice_no",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Sales Invoice No",
- "no_copy": 1,
- "options": "Sales Invoice",
- "print_hide": 1
- },
- {
"depends_on": "eval:(doc.purpose==\"Sales Return\" || doc.purpose==\"Purchase Return\")",
"doctype": "DocField",
"fieldname": "contact_section",
"fieldtype": "Section Break",
- "label": "Contact Info"
+ "label": "Contact Info",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -371,6 +401,7 @@
"oldfieldtype": "Link",
"options": "Supplier",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -406,6 +437,7 @@
"oldfieldname": "supplier_address",
"oldfieldtype": "Small Text",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -424,6 +456,7 @@
"oldfieldtype": "Link",
"options": "Customer",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -459,6 +492,7 @@
"oldfieldname": "customer_address",
"oldfieldtype": "Small Text",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -468,13 +502,15 @@
"fieldname": "more_info",
"fieldtype": "Section Break",
"label": "More Info",
- "oldfieldtype": "Section Break"
+ "oldfieldtype": "Section Break",
+ "read_only": 0
},
{
"doctype": "DocField",
"fieldname": "col4",
"fieldtype": "Column Break",
"print_width": "50%",
+ "read_only": 0,
"width": "50%"
},
{
@@ -485,7 +521,8 @@
"label": "Project Name",
"oldfieldname": "project_name",
"oldfieldtype": "Link",
- "options": "Project"
+ "options": "Project",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -500,6 +537,7 @@
"oldfieldtype": "Link",
"options": "Print Heading",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -517,6 +555,7 @@
"oldfieldtype": "Link",
"options": "Company",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0
@@ -526,6 +565,7 @@
"fieldname": "col5",
"fieldtype": "Column Break",
"print_width": "50%",
+ "read_only": 0,
"width": "50%"
},
{
@@ -558,6 +598,7 @@
"oldfieldname": "remarks",
"oldfieldtype": "Text",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -569,5 +610,13 @@
{
"doctype": "DocPerm",
"role": "Manufacturing User"
+ },
+ {
+ "doctype": "DocPerm",
+ "role": "Manufacturing Manager"
+ },
+ {
+ "doctype": "DocPerm",
+ "role": "Material Manager"
}
]
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py
index 39ec58a..ded71db 100644
--- a/stock/doctype/stock_entry/test_stock_entry.py
+++ b/stock/doctype/stock_entry/test_stock_entry.py
@@ -3,11 +3,15 @@
from __future__ import unicode_literals
import webnotes, unittest
+from webnotes.utils import flt
class TestStockEntry(unittest.TestCase):
def test_auto_material_request(self):
webnotes.conn.sql("""delete from `tabMaterial Request Item`""")
webnotes.conn.sql("""delete from `tabMaterial Request`""")
+ self._clear_stock()
+
+ webnotes.conn.set_value("Global Defaults", None, "auto_indent", True)
st1 = webnotes.bean(copy=test_records[0])
st1.insert()
@@ -21,7 +25,532 @@
where item_code='_Test Item'""")
self.assertTrue(mr_name)
+
+ def test_material_receipt_gl_entry(self):
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ mr = webnotes.bean(copy=test_records[0])
+ mr.insert()
+ mr.submit()
+
+ stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
+ "stock_in_hand_account")
+
+ self.check_stock_ledger_entries("Stock Entry", mr.doc.name,
+ [["_Test Item", "_Test Warehouse", 50.0]])
+
+ self.check_gl_entries("Stock Entry", mr.doc.name,
+ sorted([
+ [stock_in_hand_account, 5000.0, 0.0],
+ ["Stock Adjustment - _TC", 0.0, 5000.0]
+ ])
+ )
+
+ mr.cancel()
+ self.check_stock_ledger_entries("Stock Entry", mr.doc.name,
+ sorted([["_Test Item", "_Test Warehouse", 50.0],
+ ["_Test Item", "_Test Warehouse", -50.0]]))
+
+ self.check_gl_entries("Stock Entry", mr.doc.name,
+ sorted([
+ [stock_in_hand_account, 5000.0, 0.0],
+ ["Stock Adjustment - _TC", 0.0, 5000.0],
+ [stock_in_hand_account, 0.0, 5000.0],
+ ["Stock Adjustment - _TC", 5000.0, 0.0]
+ ])
+ )
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+ def test_material_issue_gl_entry(self):
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ mr = webnotes.bean(copy=test_records[0])
+ mr.insert()
+ mr.submit()
+
+ mi = webnotes.bean(copy=test_records[1])
+ mi.insert()
+ mi.submit()
+
+ stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
+ "stock_in_hand_account")
+
+ self.check_stock_ledger_entries("Stock Entry", mi.doc.name,
+ [["_Test Item", "_Test Warehouse", -40.0]])
+
+ self.check_gl_entries("Stock Entry", mi.doc.name,
+ sorted([
+ [stock_in_hand_account, 0.0, 4000.0],
+ ["Stock Adjustment - _TC", 4000.0, 0.0]
+ ])
+ )
+
+ mi.cancel()
+
+ self.check_stock_ledger_entries("Stock Entry", mi.doc.name,
+ sorted([["_Test Item", "_Test Warehouse", -40.0],
+ ["_Test Item", "_Test Warehouse", 40.0]]))
+
+ self.check_gl_entries("Stock Entry", mi.doc.name,
+ sorted([
+ [stock_in_hand_account, 0.0, 4000.0],
+ ["Stock Adjustment - _TC", 4000.0, 0.0],
+ [stock_in_hand_account, 4000.0, 0.0],
+ ["Stock Adjustment - _TC", 0.0, 4000.0],
+ ])
+ )
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+ def test_material_transfer_gl_entry(self):
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ mr = webnotes.bean(copy=test_records[0])
+ mr.insert()
+ mr.submit()
+
+ mtn = webnotes.bean(copy=test_records[2])
+ mtn.insert()
+ mtn.submit()
+
+ self.check_stock_ledger_entries("Stock Entry", mtn.doc.name,
+ [["_Test Item", "_Test Warehouse", -45.0], ["_Test Item", "_Test Warehouse 1", 45.0]])
+
+ # no gl entry
+ gl_entries = webnotes.conn.sql("""select * from `tabGL Entry`
+ where voucher_type = 'Stock Entry' and voucher_no=%s""", mtn.doc.name)
+ self.assertFalse(gl_entries)
+
+ mtn.cancel()
+ self.check_stock_ledger_entries("Stock Entry", mtn.doc.name,
+ sorted([["_Test Item", "_Test Warehouse", 45.0],
+ ["_Test Item", "_Test Warehouse 1", -45.0],
+ ["_Test Item", "_Test Warehouse", -45.0],
+ ["_Test Item", "_Test Warehouse 1", 45.0]]))
+
+ # no gl entry
+ gl_entries = webnotes.conn.sql("""select * from `tabGL Entry`
+ where voucher_type = 'Stock Entry' and voucher_no=%s""", mtn.doc.name)
+ self.assertFalse(gl_entries)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+ def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
+ # check stock ledger entries
+ sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` where voucher_type = %s
+ and voucher_no = %s order by item_code, warehouse, actual_qty""",
+ (voucher_type, voucher_no), as_dict=1)
+ self.assertTrue(sle)
+
+ for i, sle in enumerate(sle):
+ self.assertEquals(expected_sle[i][0], sle.item_code)
+ self.assertEquals(expected_sle[i][1], sle.warehouse)
+ self.assertEquals(expected_sle[i][2], sle.actual_qty)
+
+ def check_gl_entries(self, voucher_type, voucher_no, expected_gl_entries):
+ # check gl entries
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type=%s and voucher_no=%s
+ order by account asc, debit asc""", (voucher_type, voucher_no), as_dict=1)
+ self.assertTrue(gl_entries)
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_gl_entries[i][0], gle.account)
+ self.assertEquals(expected_gl_entries[i][1], gle.debit)
+ self.assertEquals(expected_gl_entries[i][2], gle.credit)
+
+ def _clear_stock(self):
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+ webnotes.conn.sql("""delete from `tabBin`""")
+
+ def _insert_material_receipt(self):
+ self._clear_stock()
+ se1 = webnotes.bean(copy=test_records[0])
+ se1.insert()
+ se1.submit()
+
+ se2 = webnotes.bean(copy=test_records[0])
+ se2.doclist[1].item_code = "_Test Item Home Desktop 100"
+ se2.insert()
+ se2.submit()
+
+ def _get_actual_qty(self):
+ return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
+ "warehouse": "_Test Warehouse"}, "actual_qty"))
+
+ def _test_sales_invoice_return(self, item_code, delivered_qty, returned_qty):
+ from stock.doctype.stock_entry.stock_entry import NotUpdateStockError
+
+ from accounts.doctype.sales_invoice.test_sales_invoice \
+ import test_records as sales_invoice_test_records
+
+ # invalid sales invoice as update stock not checked
+ si = webnotes.bean(copy=sales_invoice_test_records[1])
+ si.insert()
+ si.submit()
+
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Sales Return"
+ se.doc.sales_invoice_no = si.doc.name
+ se.doclist[1].qty = returned_qty
+ se.doclist[1].transfer_qty = returned_qty
+ self.assertRaises(NotUpdateStockError, se.insert)
+
+ self._insert_material_receipt()
+
+ # check currency available qty in bin
+ actual_qty_0 = self._get_actual_qty()
+
+ # insert a pos invoice with update stock
+ si = webnotes.bean(copy=sales_invoice_test_records[1])
+ si.doc.is_pos = si.doc.update_stock = 1
+ si.doclist[1].warehouse = "_Test Warehouse"
+ si.doclist[1].item_code = item_code
+ si.insert()
+ si.submit()
+
+ # check available bin qty after invoice submission
+ actual_qty_1 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
+
+ # check if item is validated
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Sales Return"
+ se.doc.sales_invoice_no = si.doc.name
+ se.doc.posting_date = "2013-03-10"
+ se.doclist[1].item_code = "_Test Item Home Desktop 200"
+ se.doclist[1].qty = returned_qty
+ se.doclist[1].transfer_qty = returned_qty
+
+ # check if stock entry gets submitted
+ self.assertRaises(webnotes.DoesNotExistError, se.insert)
+
+ # try again
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Sales Return"
+ se.doc.posting_date = "2013-03-10"
+ se.doc.sales_invoice_no = si.doc.name
+ se.doclist[1].qty = returned_qty
+ se.doclist[1].transfer_qty = returned_qty
+ # in both cases item code remains _Test Item when returning
+ se.insert()
+
+ se.submit()
+
+ # check if available qty is increased
+ actual_qty_2 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
+
+ return se
+
+ def test_sales_invoice_return_of_non_packing_item(self):
+ self._test_sales_invoice_return("_Test Item", 5, 2)
+
+ def test_sales_invoice_return_of_packing_item(self):
+ self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20)
+
+ def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty):
+ self._insert_material_receipt()
+
+ from stock.doctype.delivery_note.test_delivery_note \
+ import test_records as delivery_note_test_records
+
+ actual_qty_0 = self._get_actual_qty()
+
+ # make a delivery note based on this invoice
+ dn = webnotes.bean(copy=delivery_note_test_records[0])
+ dn.doclist[1].item_code = item_code
+ dn.insert()
+ dn.submit()
+
+ actual_qty_1 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
+
+ si_doclist = webnotes.map_doclist([
+ ["Delivery Note", "Sales Invoice"],
+ ["Delivery Note Item", "Sales Invoice Item"],
+ ["Sales Taxes and Charges", "Sales Taxes and Charges"],
+ ["Sales Team", "Sales Team"]], dn.doc.name)
+
+ si = webnotes.bean(si_doclist)
+ si.doc.posting_date = dn.doc.posting_date
+ si.doc.debit_to = "_Test Customer - _TC"
+ for d in si.doclist.get({"parentfield": "entries"}):
+ d.income_account = "Sales - _TC"
+ d.cost_center = "_Test Cost Center - _TC"
+ si.insert()
+ si.submit()
+
+ # insert and submit stock entry for sales return
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Sales Return"
+ se.doc.delivery_note_no = dn.doc.name
+ se.doc.posting_date = "2013-03-10"
+ se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty
+
+ se.insert()
+ se.submit()
+
+ actual_qty_2 = self._get_actual_qty()
+ self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
+
+ return se
+
+ def test_delivery_note_return_of_non_packing_item(self):
+ self._test_delivery_note_return("_Test Item", 5, 2)
+
+ def test_delivery_note_return_of_packing_item(self):
+ self._test_delivery_note_return("_Test Sales BOM Item", 25, 20)
+
+ def _test_sales_return_jv(self, se):
+ from stock.doctype.stock_entry.stock_entry import make_return_jv
+ jv_list = make_return_jv(se.doc.name)
+
+ self.assertEqual(len(jv_list), 3)
+ self.assertEqual(jv_list[0].get("voucher_type"), "Credit Note")
+ self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date)
+ self.assertEqual(jv_list[1].get("account"), "_Test Customer - _TC")
+ self.assertEqual(jv_list[2].get("account"), "Sales - _TC")
+ self.assertTrue(jv_list[1].get("against_invoice"))
+
+ def test_make_return_jv_for_sales_invoice_non_packing_item(self):
+ se = self._test_sales_invoice_return("_Test Item", 5, 2)
+ self._test_sales_return_jv(se)
+
+ def test_make_return_jv_for_sales_invoice_packing_item(self):
+ se = self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20)
+ self._test_sales_return_jv(se)
+
+ def test_make_return_jv_for_delivery_note_non_packing_item(self):
+ se = self._test_delivery_note_return("_Test Item", 5, 2)
+ self._test_sales_return_jv(se)
+
+ se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2)
+ self._test_sales_return_jv(se)
+
+ def test_make_return_jv_for_delivery_note_packing_item(self):
+ se = self._test_delivery_note_return("_Test Sales BOM Item", 25, 20)
+ self._test_sales_return_jv(se)
+
+ se = self._test_delivery_note_return_against_sales_order("_Test Sales BOM Item", 25, 20)
+ self._test_sales_return_jv(se)
+
+ def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty):
+ self._insert_material_receipt()
+
+ from selling.doctype.sales_order.test_sales_order \
+ import test_records as sales_order_test_records
+
+ actual_qty_0 = self._get_actual_qty()
+
+ so = webnotes.bean(copy=sales_order_test_records[0])
+ so.doclist[1].item_code = item_code
+ so.doclist[1].qty = 5.0
+ so.insert()
+ so.submit()
+
+ dn_doclist = webnotes.map_doclist([
+ ["Sales Order", "Delivery Note"],
+ ["Sales Order Item", "Delivery Note Item"],
+ ["Sales Taxes and Charges", "Sales Taxes and Charges"],
+ ["Sales Team", "Sales Team"]], so.doc.name)
+
+ dn = webnotes.bean(dn_doclist)
+ dn.doc.status = "Draft"
+ dn.doc.posting_date = so.doc.delivery_date
+ dn.insert()
+ dn.submit()
+
+ actual_qty_1 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
+
+ si_doclist = webnotes.map_doclist([
+ ["Sales Order", "Sales Invoice"],
+ ["Sales Order Item", "Sales Invoice Item"],
+ ["Sales Taxes and Charges", "Sales Taxes and Charges"],
+ ["Sales Team", "Sales Team"]], so.doc.name)
+
+ si = webnotes.bean(si_doclist)
+ si.doc.posting_date = dn.doc.posting_date
+ si.doc.debit_to = "_Test Customer - _TC"
+ for d in si.doclist.get({"parentfield": "entries"}):
+ d.income_account = "Sales - _TC"
+ d.cost_center = "_Test Cost Center - _TC"
+ si.insert()
+ si.submit()
+
+ # insert and submit stock entry for sales return
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Sales Return"
+ se.doc.delivery_note_no = dn.doc.name
+ se.doc.posting_date = "2013-03-10"
+ se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty
+
+ se.insert()
+ se.submit()
+
+ actual_qty_2 = self._get_actual_qty()
+ self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
+
+ return se
+
+ def test_purchase_receipt_return(self):
+ self._clear_stock()
+
+ actual_qty_0 = self._get_actual_qty()
+
+ from stock.doctype.purchase_receipt.test_purchase_receipt \
+ import test_records as purchase_receipt_test_records
+
+ # submit purchase receipt
+ pr = webnotes.bean(copy=purchase_receipt_test_records[0])
+ pr.insert()
+ pr.submit()
+
+ actual_qty_1 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_0 + 10, actual_qty_1)
+
+ pi_doclist = webnotes.map_doclist([
+ ["Purchase Receipt", "Purchase Invoice"],
+ ["Purchase Receipt Item", "Purchase Invoice Item"],
+ ["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], pr.doc.name)
+
+ pi = webnotes.bean(pi_doclist)
+ pi.doc.posting_date = pr.doc.posting_date
+ pi.doc.credit_to = "_Test Supplier - _TC"
+ for d in pi.doclist.get({"parentfield": "entries"}):
+ d.expense_head = "_Test Account Cost for Goods Sold - _TC"
+ d.cost_center = "_Test Cost Center - _TC"
+ for d in pi.doclist.get({"parentfield": "purchase_tax_details"}):
+ d.cost_center = "_Test Cost Center - _TC"
+
+ pi.run_method("calculate_taxes_and_totals")
+ pi.insert()
+ pi.submit()
+
+ # submit purchase return
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Purchase Return"
+ se.doc.purchase_receipt_no = pr.doc.name
+ se.doc.posting_date = "2013-03-01"
+ se.doclist[1].qty = se.doclist[1].transfer_qty = 5
+ se.doclist[1].s_warehouse = "_Test Warehouse"
+ se.insert()
+ se.submit()
+
+ actual_qty_2 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_1 - 5, actual_qty_2)
+
+ return se, pr.doc.name
+
+ def test_over_stock_return(self):
+ from stock.doctype.stock_entry.stock_entry import StockOverReturnError
+
+ # out of 10, 5 gets returned
+ prev_se, pr_docname = self.test_purchase_receipt_return()
+
+ # submit purchase return - return another 6 qtys so that exception is raised
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Purchase Return"
+ se.doc.purchase_receipt_no = pr_docname
+ se.doc.posting_date = "2013-03-01"
+ se.doclist[1].qty = se.doclist[1].transfer_qty = 6
+ se.doclist[1].s_warehouse = "_Test Warehouse"
+
+ self.assertRaises(StockOverReturnError, se.insert)
+
+ def _test_purchase_return_jv(self, se):
+ from stock.doctype.stock_entry.stock_entry import make_return_jv
+ jv_list = make_return_jv(se.doc.name)
+
+ self.assertEqual(len(jv_list), 3)
+ self.assertEqual(jv_list[0].get("voucher_type"), "Debit Note")
+ self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date)
+ self.assertEqual(jv_list[1].get("account"), "_Test Supplier - _TC")
+ self.assertEqual(jv_list[2].get("account"), "_Test Account Cost for Goods Sold - _TC")
+ self.assertTrue(jv_list[1].get("against_voucher"))
+
+ def test_make_return_jv_for_purchase_receipt(self):
+ se, pr_name = self.test_purchase_receipt_return()
+ self._test_purchase_return_jv(se)
+
+ se, pr_name = self._test_purchase_return_return_against_purchase_order()
+ self._test_purchase_return_jv(se)
+
+ def _test_purchase_return_return_against_purchase_order(self):
+ self._clear_stock()
+
+ actual_qty_0 = self._get_actual_qty()
+
+ from buying.doctype.purchase_order.test_purchase_order \
+ import test_records as purchase_order_test_records
+
+ # submit purchase receipt
+ po = webnotes.bean(copy=purchase_order_test_records[0])
+ po.doc.is_subcontracted = None
+ po.doclist[1].item_code = "_Test Item"
+ po.doclist[1].import_rate = 50
+ po.insert()
+ po.submit()
+
+ pr_doclist = webnotes.map_doclist([
+ ["Purchase Order", "Purchase Receipt"],
+ ["Purchase Order Item", "Purchase Receipt Item"],
+ ["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], po.doc.name)
+
+ pr = webnotes.bean(pr_doclist)
+ pr.doc.posting_date = po.doc.transaction_date
+ pr.insert()
+ pr.submit()
+
+ actual_qty_1 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_0 + 10, actual_qty_1)
+
+ pi_doclist = webnotes.map_doclist([
+ ["Purchase Order", "Purchase Invoice"],
+ ["Purchase Order Item", "Purchase Invoice Item"],
+ ["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], po.doc.name)
+
+ pi = webnotes.bean(pi_doclist)
+ pi.doc.posting_date = pr.doc.posting_date
+ pi.doc.credit_to = "_Test Supplier - _TC"
+ for d in pi.doclist.get({"parentfield": "entries"}):
+ d.expense_head = "_Test Account Cost for Goods Sold - _TC"
+ d.cost_center = "_Test Cost Center - _TC"
+ for d in pi.doclist.get({"parentfield": "purchase_tax_details"}):
+ d.cost_center = "_Test Cost Center - _TC"
+
+ pi.run_method("calculate_taxes_and_totals")
+ pi.insert()
+ pi.submit()
+
+ # submit purchase return
+ se = webnotes.bean(copy=test_records[0])
+ se.doc.purpose = "Purchase Return"
+ se.doc.purchase_receipt_no = pr.doc.name
+ se.doc.posting_date = "2013-03-01"
+ se.doclist[1].qty = se.doclist[1].transfer_qty = 5
+ se.doclist[1].s_warehouse = "_Test Warehouse"
+ se.insert()
+ se.submit()
+
+ actual_qty_2 = self._get_actual_qty()
+
+ self.assertEquals(actual_qty_1 - 5, actual_qty_2)
+
+ return se, pr.doc.name
+
test_records = [
[
{
@@ -29,7 +558,9 @@
"doctype": "Stock Entry",
"posting_date": "2013-01-25",
"posting_time": "17:14:24",
- "purpose": "Material Receipt"
+ "purpose": "Material Receipt",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "expense_adjustment_account": "Stock Adjustment - _TC"
},
{
"conversion_factor": 1.0,
@@ -50,7 +581,9 @@
"doctype": "Stock Entry",
"posting_date": "2013-01-25",
"posting_time": "17:15",
- "purpose": "Material Issue"
+ "purpose": "Material Issue",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "expense_adjustment_account": "Stock Adjustment - _TC"
},
{
"conversion_factor": 1.0,
@@ -71,12 +604,14 @@
"doctype": "Stock Entry",
"posting_date": "2013-01-25",
"posting_time": "17:14:24",
- "purpose": "Material Transfer"
+ "purpose": "Material Transfer",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "expense_adjustment_account": "Stock Adjustment - _TC"
},
{
"conversion_factor": 1.0,
"doctype": "Stock Entry Detail",
- "item_code": "_Test Item Home Desktop 100",
+ "item_code": "_Test Item",
"parentfield": "mtn_details",
"incoming_rate": 100,
"qty": 45.0,
@@ -85,19 +620,6 @@
"uom": "_Test UOM",
"s_warehouse": "_Test Warehouse",
"t_warehouse": "_Test Warehouse 1",
- },
- {
- "conversion_factor": 1.0,
- "doctype": "Stock Entry Detail",
- "item_code": "_Test Item Home Desktop 100",
- "parentfield": "mtn_details",
- "qty": 45.0,
- "incoming_rate": 100,
- "stock_uom": "_Test UOM",
- "transfer_qty": 45.0,
- "uom": "_Test UOM",
- "s_warehouse": "_Test Warehouse",
- "t_warehouse": "_Test Warehouse 1",
}
]
]
\ No newline at end of file
diff --git a/stock/doctype/stock_entry_detail/stock_entry_detail.txt b/stock/doctype/stock_entry_detail/stock_entry_detail.txt
index bb8610c..2c59dd7 100644
--- a/stock/doctype/stock_entry_detail/stock_entry_detail.txt
+++ b/stock/doctype/stock_entry_detail/stock_entry_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-29 19:25:45",
+ "creation": "2013-02-22 01:28:04",
"docstatus": 0,
- "modified": "2013-02-20 16:46:26",
+ "modified": "2013-03-07 07:03:32",
"modified_by": "Administrator",
"owner": "Administrator"
},
diff --git a/stock/doctype/stock_ledger/stock_ledger.py b/stock/doctype/stock_ledger/stock_ledger.py
index 05fc0e0..fcb4a54 100644
--- a/stock/doctype/stock_ledger/stock_ledger.py
+++ b/stock/doctype/stock_ledger/stock_ledger.py
@@ -17,7 +17,7 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import add_days, cstr, flt, nowdate, cint
+from webnotes.utils import add_days, cstr, flt, nowdate, cint, now
from webnotes.model.doc import Document
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
@@ -49,7 +49,7 @@
serial_nos = get_valid_serial_nos(d.serial_no)
for s in serial_nos:
s = s.strip()
- sr_war = sql("select warehouse,name from `tabSerial No` where name = '%s'" % (s))
+ sr_war = webnotes.conn.sql("select warehouse,name from `tabSerial No` where name = '%s'" % (s))
if not sr_war:
msgprint("Serial No %s does not exists"%s, raise_exception = 1)
elif not sr_war[0][0]:
@@ -81,7 +81,7 @@
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec, rejected=None):
- item_details = sql("""select item_group, warranty_period
+ item_details = webnotes.conn.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)
@@ -112,7 +112,7 @@
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = '', rejected=None):
- exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
+ exists = webnotes.conn.sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
if is_submit:
if exists and exists[0][2] != 2 and purpose not in ['Material Transfer', 'Sales Return']:
msgprint("Serial No: %s already %s" % (serial_no, exists and exists[0][1]), raise_exception = 1)
@@ -126,15 +126,15 @@
if exists and exists[0][1] == 'Delivered' and exists[0][2] != 2:
msgprint("Serial No: %s is already delivered, you can not cancel the document." % serial_no, raise_exception=1)
elif purpose == 'Material Transfer':
- sql("update `tabSerial No` set status = 'In Store', purchase_document_type = '', purchase_document_no = '', warehouse = '%s' where name = '%s'" % (d.s_warehouse, serial_no))
+ webnotes.conn.sql("update `tabSerial No` set status = 'In Store', purchase_document_type = '', purchase_document_no = '', warehouse = '%s' where name = '%s'" % (d.s_warehouse, serial_no))
elif purpose == 'Sales Return':
- sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
+ webnotes.conn.sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
else:
- sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
+ webnotes.conn.sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
def check_serial_no_exists(self, serial_no, item_code):
- chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
+ chk = webnotes.conn.sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
if not chk:
msgprint("Serial No: %s does not exists in the system" % serial_no, raise_exception=1)
elif chk and chk[0]['item_code'] != item_code:
@@ -169,7 +169,7 @@
self.check_serial_no_exists(serial_no, d.item_code)
self.set_delivery_serial_no_values(obj, serial_no)
else:
- sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
+ webnotes.conn.sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
@@ -202,17 +202,20 @@
if v.get('is_cancelled') == 'Yes':
v['actual_qty'] = -flt(v['actual_qty'])
# cancel matching entry
- sql("update `tabStock Ledger Entry` set is_cancelled='Yes' where voucher_no=%s \
- and voucher_type=%s", (v['voucher_no'], v['voucher_type']))
+ webnotes.conn.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes',
+ modified=%s, modified_by=%s
+ where voucher_no=%s and voucher_type=%s""",
+ (now(), webnotes.session.user, v['voucher_no'], v['voucher_type']))
if v.get("actual_qty"):
sle_id = self.make_entry(v)
-
+
args = v.copy()
args.update({
"sle_id": sle_id,
"is_amended": is_amended
})
+
get_obj('Warehouse', v["warehouse"]).update_bin(args)
@@ -230,5 +233,5 @@
"""
Repost everything!
"""
- for wh in sql("select name from tabWarehouse"):
+ for wh in webnotes.conn.sql("select name from tabWarehouse"):
get_obj('Warehouse', wh[0]).repost_stock()
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index d1fe3d9..3089a57 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -39,7 +39,7 @@
self.check_stock_frozen_date()
self.scrub_posting_time()
self.doc.fiscal_year = get_fiscal_year(self.doc.posting_date)[0]
-
+
#check for item quantity available in stock
def actual_amt_check(self):
if self.doc.batch_no:
diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.js b/stock/doctype/stock_reconciliation/stock_reconciliation.js
index f1508ac..372166e 100644
--- a/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -18,6 +18,44 @@
wn.provide("erpnext.stock");
erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
+ onload: function() {
+ this.set_default_expense_account();
+ },
+
+ set_default_expense_account: function() {
+ var me = this;
+
+ if (sys_defaults.auto_inventory_accounting && !this.frm.doc.expense_account) {
+ this.frm.call({
+ method: "controllers.accounts_controller.get_default_account",
+ args: {
+ "account_for": "stock_adjustment_account",
+ "company": this.frm.doc.company
+ },
+ callback: function(r) {
+ if (!r.exc) me.frm.set_value("expense_account", r.message);
+ }
+ });
+ }
+ },
+
+ setup: function() {
+ var me = this;
+
+ this.frm.add_fetch("company", "expense_account", "stock_adjustment_account");
+
+ this.frm.fields_dict["expense_account"].get_query = function() {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": {
+ "is_pl_account": "Yes",
+ "debit_or_credit": "Debit",
+ "company": me.frm.doc.company
+ }
+ }
+ }
+ },
+
refresh: function() {
if(this.frm.doc.docstatus===0) {
this.show_download_template();
diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.py b/stock/doctype/stock_reconciliation/stock_reconciliation.py
index e0f7f09..ac0ab98 100644
--- a/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -18,22 +18,26 @@
import webnotes
import json
from webnotes import msgprint, _
-from webnotes.utils import cstr, flt
-from webnotes.model.controller import DocListController
+from webnotes.utils import cstr, flt, cint
from stock.stock_ledger import update_entries_after
+from controllers.stock_controller import StockController
-class DocType(DocListController):
+class DocType(StockController):
def setup(self):
self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
+ self.entries = []
def validate(self):
self.validate_data()
def on_submit(self):
self.insert_stock_ledger_entries()
+ self.set_stock_value_difference()
+ self.make_gl_entries()
def on_cancel(self):
self.delete_stock_ledger_entries()
+ self.make_gl_entries()
def validate_data(self):
if not self.doc.reconciliation_json:
@@ -134,6 +138,7 @@
data = json.loads(self.doc.reconciliation_json)
for row_num, row in enumerate(data[data.index(self.head_row)+1:]):
row = webnotes._dict(zip(row_template, row))
+ row["row_num"] = row_num
previous_sle = get_previous_sle({
"item_code": row.item_code,
"warehouse": row.warehouse,
@@ -162,8 +167,7 @@
def sle_for_moving_avg(self, row, previous_sle, change_in_qty, change_in_rate):
"""Insert Stock Ledger Entries for Moving Average valuation"""
- def _get_incoming_rate(qty, valuation_rate, previous_qty,
- previous_valuation_rate):
+ def _get_incoming_rate(qty, valuation_rate, previous_qty, previous_valuation_rate):
if previous_valuation_rate == 0:
return flt(valuation_rate)
else:
@@ -177,9 +181,9 @@
incoming_rate = _get_incoming_rate(flt(row.qty), flt(row.valuation_rate),
flt(previous_sle.get("qty_after_transaction")),
flt(previous_sle.get("valuation_rate")))
-
- self.insert_entries({"actual_qty": change_in_qty,
- "incoming_rate": incoming_rate}, row)
+
+ row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Actual Entry"
+ self.insert_entries({"actual_qty": change_in_qty, "incoming_rate": incoming_rate}, row)
elif change_in_rate and flt(previous_sle.get("qty_after_transaction")) > 0:
# if no change in qty, but change in rate
@@ -190,9 +194,11 @@
flt(previous_sle.get("valuation_rate")))
# +1 entry
+ row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Valuation Adjustment +1"
self.insert_entries({"actual_qty": 1, "incoming_rate": incoming_rate}, row)
# -1 entry
+ row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Valuation Adjustment -1"
self.insert_entries({"actual_qty": -1}, row)
def sle_for_fifo(self, row, previous_sle, change_in_qty, change_in_rate):
@@ -206,14 +212,16 @@
if previous_stock_queue != [[row.qty, row.valuation_rate]]:
# make entry as per attachment
if row.qty:
+ row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Actual Entry"
self.insert_entries({"actual_qty": row.qty,
"incoming_rate": flt(row.valuation_rate)}, row)
# Make reverse entry
if previous_stock_qty:
+ row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Reverse Entry"
self.insert_entries({"actual_qty": -1 * previous_stock_qty,
- "incoming_rate": previous_stock_qty < 0 and \
- flt(row.valuation_rate) or 0}, row)
+ "incoming_rate": previous_stock_qty < 0 and
+ flt(row.valuation_rate) or 0}, row)
if change_in_qty:
@@ -221,8 +229,7 @@
# dont want change in valuation
if previous_stock_qty > 0:
# set valuation_rate as previous valuation_rate
- row.valuation_rate = \
- previous_stock_value / flt(previous_stock_qty)
+ row.valuation_rate = previous_stock_value / flt(previous_stock_qty)
_insert_entries()
@@ -234,8 +241,8 @@
_insert_entries()
def insert_entries(self, opts, row):
- """Insert Stock Ledger Entries"""
- args = {
+ """Insert Stock Ledger Entries"""
+ args = webnotes._dict({
"doctype": "Stock Ledger Entry",
"item_code": row.item_code,
"warehouse": row.warehouse,
@@ -243,9 +250,10 @@
"posting_time": self.doc.posting_time,
"voucher_type": self.doc.doctype,
"voucher_no": self.doc.name,
- "company": webnotes.conn.get_default("company"),
+ "company": self.doc.company,
"is_cancelled": "No",
- }
+ "voucher_detail_no": row.voucher_detail_no
+ })
args.update(opts)
# create stock ledger entry
sle_wrapper = webnotes.bean([args])
@@ -254,17 +262,18 @@
# update bin
webnotes.get_obj('Warehouse', row.warehouse).update_bin(args)
-
- return sle_wrapper
+
+ # append to entries
+ self.entries.append(args)
def delete_stock_ledger_entries(self):
""" Delete Stock Ledger Entries related to this Stock Reconciliation
and repost future Stock Ledger Entries"""
-
+
existing_entries = webnotes.conn.sql("""select item_code, warehouse
- from `tabStock Ledger Entry` where voucher_type='Stock Reconciliation'
+ from `tabStock Ledger Entry` where voucher_type='Stock Reconciliation'
and voucher_no=%s""", self.doc.name, as_dict=1)
-
+
# delete entries
webnotes.conn.sql("""delete from `tabStock Ledger Entry`
where voucher_type='Stock Reconciliation' and voucher_no=%s""", self.doc.name)
@@ -277,7 +286,37 @@
"posting_date": self.doc.posting_date,
"posting_time": self.doc.posting_time
})
-
+
+ def set_stock_value_difference(self):
+ """stock_value_difference is the increment in the stock value"""
+ from stock.utils import get_buying_amount
+
+ item_list = [d.item_code for d in self.entries]
+ warehouse_list = [d.warehouse for d in self.entries]
+ stock_ledger_entries = self.get_stock_ledger_entries(item_list, warehouse_list)
+
+ self.doc.stock_value_difference = 0.0
+ for d in self.entries:
+ self.doc.stock_value_difference -= get_buying_amount(d.item_code, d.warehouse,
+ d.actual_qty, self.doc.doctype, self.doc.name, d.voucher_detail_no,
+ stock_ledger_entries)
+ webnotes.conn.set(self.doc, "stock_value_difference", self.doc.stock_value_difference)
+
+ def make_gl_entries(self):
+ if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
+ return
+
+ if not self.doc.expense_account:
+ msgprint(_("Please enter Expense Account"), raise_exception=1)
+
+ from accounts.general_ledger import make_gl_entries
+
+ cost_center = "Auto Inventory Accounting - %s" % (self.company_abbr,)
+
+ gl_entries = self.get_gl_entries_for_stock(self.doc.expense_account,
+ self.doc.stock_value_difference, cost_center=cost_center)
+ if gl_entries:
+ make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2)
@webnotes.whitelist()
def upload():
diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.txt b/stock/doctype/stock_reconciliation/stock_reconciliation.txt
index 094e903..9137cae 100644
--- a/stock/doctype/stock_reconciliation/stock_reconciliation.txt
+++ b/stock/doctype/stock_reconciliation/stock_reconciliation.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-19 10:23:35",
+ "creation": "2013-01-22 16:50:41",
"docstatus": 0,
- "modified": "2013-01-22 14:57:24",
+ "modified": "2013-03-18 12:48:42",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -30,6 +30,7 @@
"permlevel": 0
},
{
+ "amend": 1,
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
@@ -40,6 +41,7 @@
"permlevel": 0,
"read": 1,
"report": 1,
+ "role": "Material Manager",
"submit": 1,
"write": 1
},
@@ -81,6 +83,22 @@
},
{
"doctype": "DocField",
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "label": "Company",
+ "options": "Company",
+ "reqd": 1
+ },
+ {
+ "depends_on": "eval:sys_defaults.auto_inventory_accounting",
+ "doctype": "DocField",
+ "fieldname": "expense_account",
+ "fieldtype": "Link",
+ "label": "Expense Account",
+ "options": "Account"
+ },
+ {
+ "doctype": "DocField",
"fieldname": "col1",
"fieldtype": "Column Break"
},
@@ -119,12 +137,14 @@
"read_only": 1
},
{
- "amend": 0,
- "doctype": "DocPerm",
- "role": "Material Manager"
+ "doctype": "DocField",
+ "fieldname": "stock_value_difference",
+ "fieldtype": "Currency",
+ "hidden": 1,
+ "label": "Stock Value Difference",
+ "print_hide": 1
},
{
- "doctype": "DocPerm",
- "role": "System Manager"
+ "doctype": "DocPerm"
}
]
\ No newline at end of file
diff --git a/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index 80579ae..cebc6ff 100644
--- a/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -1,40 +1,15 @@
# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
+# For license information, please see license.txt
from __future__ import unicode_literals
-import unittest
-import webnotes
-from webnotes.tests import insert_test_data
+import webnotes, unittest
from webnotes.utils import flt
import json
-
-company = webnotes.conn.get_default("company")
+from accounts.utils import get_fiscal_year
class TestStockReconciliation(unittest.TestCase):
- def setUp(self):
- webnotes.conn.begin()
- self.insert_test_data()
-
- def tearDown(self):
- # print "Message Log:", "\n--\n".join(webnotes.message_log)
- # print "Debug Log:", "\n--\n".join(webnotes.debug_log)
- webnotes.conn.rollback()
-
def test_reco_for_fifo(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
# [[qty, valuation_rate, posting_date,
# posting_time, expected_stock_value, bin_qty, bin_valuation]]
input_data = [
@@ -53,28 +28,32 @@
]
for d in input_data:
+ self.cleanup_data()
self.insert_existing_sle("FIFO")
-
- self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
+ stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
+ # check stock value
res = webnotes.conn.sql("""select stock_value from `tabStock Ledger Entry`
- where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'
+ where item_code = '_Test Item' and warehouse = '_Test Warehouse'
and posting_date = %s and posting_time = %s order by name desc limit 1""",
(d[2], d[3]))
-
self.assertEqual(res and flt(res[0][0]) or 0, d[4])
+ # check bin qty and stock value
bin = webnotes.conn.sql("""select actual_qty, stock_value from `tabBin`
- where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'""")
+ where item_code = '_Test Item' and warehouse = '_Test Warehouse'""")
self.assertEqual(bin and [flt(bin[0][0]), flt(bin[0][1])] or [], [d[5], d[6]])
+ # no gl entries
+ gl_entries = webnotes.conn.sql("""select name from `tabGL Entry`
+ where voucher_type = 'Stock Reconciliation' and voucher_no = %s""",
+ stock_reco.doc.name)
+ self.assertFalse(gl_entries)
- self.tearDown()
- self.setUp()
-
def test_reco_for_moving_average(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
# [[qty, valuation_rate, posting_date,
# posting_time, expected_stock_value, bin_qty, bin_valuation]]
input_data = [
@@ -94,95 +73,194 @@
]
for d in input_data:
+ self.cleanup_data()
self.insert_existing_sle("Moving Average")
+ stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
- self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
-
+ # check stock value in sle
res = webnotes.conn.sql("""select stock_value from `tabStock Ledger Entry`
- where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'
+ where item_code = '_Test Item' and warehouse = '_Test Warehouse'
and posting_date = %s and posting_time = %s order by name desc limit 1""",
(d[2], d[3]))
self.assertEqual(res and flt(res[0][0], 4) or 0, d[4])
+ # bin qty and stock value
bin = webnotes.conn.sql("""select actual_qty, stock_value from `tabBin`
- where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'""")
+ where item_code = '_Test Item' and warehouse = '_Test Warehouse'""")
self.assertEqual(bin and [flt(bin[0][0]), flt(bin[0][1], 4)] or [],
[flt(d[5]), flt(d[6])])
-
- self.tearDown()
- self.setUp()
+
+ # no gl entries
+ gl_entries = webnotes.conn.sql("""select name from `tabGL Entry`
+ where voucher_type = 'Stock Reconciliation' and voucher_no = %s""",
+ stock_reco.doc.name)
+ self.assertFalse(gl_entries)
+ def test_reco_fifo_gl_entries(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ # [[qty, valuation_rate, posting_date,
+ # posting_time, stock_in_hand_debit]]
+ input_data = [
+ [50, 1000, "2012-12-26", "12:00", 38000],
+ [5, 1000, "2012-12-26", "12:00", -7000],
+ [15, 1000, "2012-12-26", "12:00", 3000],
+ [25, 900, "2012-12-26", "12:00", 10500],
+ [20, 500, "2012-12-26", "12:00", -2000],
+ ["", 1000, "2012-12-26", "12:05", 3000],
+ [20, "", "2012-12-26", "12:05", 4000],
+ [10, 2000, "2012-12-26", "12:10", 8000],
+ [0, "", "2012-12-26", "12:10", -12000],
+ [50, 1000, "2013-01-01", "12:00", 50000],
+ [5, 1000, "2013-01-01", "12:00", 5000],
+ [1, 1000, "2012-12-01", "00:00", 1000],
+
+ ]
+
+ for d in input_data:
+ self.cleanup_data()
+ self.insert_existing_sle("FIFO")
+ stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
+
+ # check gl_entries
+ self.check_gl_entries(stock_reco.doc.name, d[4])
+
+ # cancel
+ stock_reco.cancel()
+ self.check_gl_entries(stock_reco.doc.name, -d[4], True)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+ def test_reco_moving_average_gl_entries(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ # [[qty, valuation_rate, posting_date,
+ # posting_time, stock_in_hand_debit]]
+ input_data = [
+ [50, 1000, "2012-12-26", "12:00", 36500],
+ [5, 1000, "2012-12-26", "12:00", -8500],
+ [15, 1000, "2012-12-26", "12:00", 1500],
+ [25, 900, "2012-12-26", "12:00", 9000],
+ [20, 500, "2012-12-26", "12:00", -3500],
+ ["", 1000, "2012-12-26", "12:05", 1500],
+ [20, "", "2012-12-26", "12:05", 4500],
+ [10, 2000, "2012-12-26", "12:10", 6500],
+ [0, "", "2012-12-26", "12:10", -13500],
+ [50, 1000, "2013-01-01", "12:00", 50000],
+ [5, 1000, "2013-01-01", "12:00", 5000],
+ [1, 1000, "2012-12-01", "00:00", 1000],
+
+ ]
+
+ for d in input_data:
+ self.cleanup_data()
+ self.insert_existing_sle("Moving Average")
+ stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
+
+ # check gl_entries
+ self.check_gl_entries(stock_reco.doc.name, d[4])
+
+ # cancel
+ stock_reco.cancel()
+ self.check_gl_entries(stock_reco.doc.name, -d[4], True)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+
+ def cleanup_data(self):
+ webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+ webnotes.conn.sql("delete from tabBin")
+
def submit_stock_reconciliation(self, qty, rate, posting_date, posting_time):
- return webnotes.bean([{
+ stock_reco = webnotes.bean([{
"doctype": "Stock Reconciliation",
- "name": "RECO-001",
- "__islocal": 1,
"posting_date": posting_date,
"posting_time": posting_time,
+ "fiscal_year": get_fiscal_year(posting_date)[0],
+ "company": "_Test Company",
+ "expense_account": "Stock Adjustment - _TC",
"reconciliation_json": json.dumps([
["Item Code", "Warehouse", "Quantity", "Valuation Rate"],
- ["Android Jack D", "Default Warehouse", qty, rate]
+ ["_Test Item", "_Test Warehouse", qty, rate]
]),
- }]).submit()
+ }])
+ stock_reco.insert()
+ stock_reco.submit()
+ return stock_reco
- def insert_test_data(self):
- # create default warehouse
- if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
- webnotes.insert({"doctype": "Warehouse",
- "warehouse_name": "Default Warehouse",
- "warehouse_type": "Stores"})
-
- # create UOM: Nos.
- if not webnotes.conn.exists("UOM", "Nos"):
- webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
-
- # create item groups and items
- insert_test_data("Item Group",
- sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
- insert_test_data("Item")
+ def check_gl_entries(self, voucher_no, stock_value_diff, cancel=None):
+ stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
+ "stock_in_hand_account")
+ debit_amount = stock_value_diff > 0 and stock_value_diff or 0.0
+ credit_amount = stock_value_diff < 0 and abs(stock_value_diff) or 0.0
+
+ expected_gl_entries = sorted([
+ [stock_in_hand_account, debit_amount, credit_amount],
+ ["Stock Adjustment - _TC", credit_amount, debit_amount]
+ ])
+ if cancel:
+ expected_gl_entries = sorted([
+ [stock_in_hand_account, debit_amount, credit_amount],
+ ["Stock Adjustment - _TC", credit_amount, debit_amount],
+ [stock_in_hand_account, credit_amount, debit_amount],
+ ["Stock Adjustment - _TC", debit_amount, credit_amount]
+ ])
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Stock Reconciliation' and voucher_no=%s
+ order by account asc, debit asc""", voucher_no, as_dict=1)
+ self.assertTrue(gl_entries)
+
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_gl_entries[i][0], gle.account)
+ self.assertEquals(expected_gl_entries[i][1], gle.debit)
+ self.assertEquals(expected_gl_entries[i][2], gle.credit)
def insert_existing_sle(self, valuation_method):
- webnotes.conn.set_value("Item", "Android Jack D", "valuation_method", valuation_method)
+ webnotes.conn.set_value("Item", "_Test Item", "valuation_method", valuation_method)
webnotes.conn.set_default("allow_negative_stock", 1)
existing_ledgers = [
{
"doctype": "Stock Ledger Entry", "__islocal": 1,
"voucher_type": "Stock Entry", "voucher_no": "TEST",
- "item_code": "Android Jack D", "warehouse": "Default Warehouse",
+ "item_code": "_Test Item", "warehouse": "_Test Warehouse",
"posting_date": "2012-12-12", "posting_time": "01:00",
- "actual_qty": 20, "incoming_rate": 1000, "company": company
+ "actual_qty": 20, "incoming_rate": 1000, "company": "_Test Company"
},
{
"doctype": "Stock Ledger Entry", "__islocal": 1,
"voucher_type": "Stock Entry", "voucher_no": "TEST",
- "item_code": "Android Jack D", "warehouse": "Default Warehouse",
+ "item_code": "_Test Item", "warehouse": "_Test Warehouse",
"posting_date": "2012-12-15", "posting_time": "02:00",
- "actual_qty": 10, "incoming_rate": 700, "company": company
+ "actual_qty": 10, "incoming_rate": 700, "company": "_Test Company"
},
{
"doctype": "Stock Ledger Entry", "__islocal": 1,
"voucher_type": "Stock Entry", "voucher_no": "TEST",
- "item_code": "Android Jack D", "warehouse": "Default Warehouse",
+ "item_code": "_Test Item", "warehouse": "_Test Warehouse",
"posting_date": "2012-12-25", "posting_time": "03:00",
- "actual_qty": -15, "company": company
+ "actual_qty": -15, "company": "_Test Company"
},
{
"doctype": "Stock Ledger Entry", "__islocal": 1,
"voucher_type": "Stock Entry", "voucher_no": "TEST",
- "item_code": "Android Jack D", "warehouse": "Default Warehouse",
+ "item_code": "_Test Item", "warehouse": "_Test Warehouse",
"posting_date": "2012-12-31", "posting_time": "08:00",
- "actual_qty": -20, "company": company
+ "actual_qty": -20, "company": "_Test Company"
},
{
"doctype": "Stock Ledger Entry", "__islocal": 1,
"voucher_type": "Stock Entry", "voucher_no": "TEST",
- "item_code": "Android Jack D", "warehouse": "Default Warehouse",
+ "item_code": "_Test Item", "warehouse": "_Test Warehouse",
"posting_date": "2013-01-05", "posting_time": "07:00",
- "actual_qty": 15, "incoming_rate": 1200, "company": company
+ "actual_qty": 15, "incoming_rate": 1200, "company": "_Test Company"
},
]
- webnotes.get_obj("Stock Ledger").update_stock(existing_ledgers)
\ No newline at end of file
+ webnotes.get_obj("Stock Ledger").update_stock(existing_ledgers)
+
+
+test_dependencies = ["Item", "Warehouse"]
\ No newline at end of file
diff --git a/stock/doctype/uom_conversion_detail/uom_conversion_detail.txt b/stock/doctype/uom_conversion_detail/uom_conversion_detail.txt
index f0edf03..381c7f7 100644
--- a/stock/doctype/uom_conversion_detail/uom_conversion_detail.txt
+++ b/stock/doctype/uom_conversion_detail/uom_conversion_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:40",
+ "creation": "2013-02-22 01:28:04",
"docstatus": 0,
- "modified": "2012-03-27 14:36:40",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -11,10 +11,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Stock",
- "name": "__common__",
- "section_style": "Tray",
- "show_in_menu": 0,
- "version": 1
+ "name": "__common__"
},
{
"doctype": "DocField",
diff --git a/stock/doctype/warehouse/warehouse.txt b/stock/doctype/warehouse/warehouse.txt
index d0dd73c..d08b3cc 100644
--- a/stock/doctype/warehouse/warehouse.txt
+++ b/stock/doctype/warehouse/warehouse.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:30",
+ "creation": "2013-03-07 18:50:32",
"docstatus": 0,
- "modified": "2013-02-04 11:35:53",
+ "modified": "2013-03-11 17:58:45",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -21,7 +21,8 @@
"name": "__common__",
"parent": "Warehouse",
"parentfield": "fields",
- "parenttype": "DocType"
+ "parenttype": "DocType",
+ "read_only": 0
},
{
"doctype": "DocPerm",
@@ -190,7 +191,7 @@
"permlevel": 0
},
{
- "description": "This feature is for merging duplicate warehouses. It will replace all the links of this warehouse by \"Merge With\" warehouse. After merging you can delete this warehouse, as stock level for this warehouse will be zero.",
+ "description": "This feature is for merging duplicate warehouses. It will replace all the links of this warehouse by \"Merge Into\" warehouse. After merging you can delete this warehouse, as stock level for this warehouse will be zero.",
"doctype": "DocField",
"fieldname": "merge_warehouses_section",
"fieldtype": "Section Break",
@@ -201,7 +202,7 @@
"doctype": "DocField",
"fieldname": "merge_with",
"fieldtype": "Link",
- "label": "Merge With",
+ "label": "Merge Into",
"options": "Warehouse",
"permlevel": 2
},
@@ -222,24 +223,6 @@
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "doctype": "DocPerm",
- "permlevel": 0,
- "role": "Material User",
- "write": 0
- },
- {
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "doctype": "DocPerm",
- "permlevel": 2,
- "role": "Material User",
- "write": 0
- },
- {
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
@@ -248,6 +231,26 @@
"write": 1
},
{
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 0,
+ "role": "Material Manager",
+ "write": 0
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 0,
+ "role": "Material User",
+ "write": 0
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 2,
diff --git a/stock/doctype/warehouse_user/warehouse_user.txt b/stock/doctype/warehouse_user/warehouse_user.txt
index 6cb02ae..6912e30 100644
--- a/stock/doctype/warehouse_user/warehouse_user.txt
+++ b/stock/doctype/warehouse_user/warehouse_user.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-04 11:33:57",
+ "creation": "2013-02-22 01:28:05",
"docstatus": 0,
- "modified": "2013-02-04 11:36:16",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -24,6 +24,7 @@
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
+ "print_width": "200px",
"width": "200px"
},
{
diff --git a/stock/page/stock_balance/stock_balance.js b/stock/page/stock_balance/stock_balance.js
index 9494f0d..47a3344 100644
--- a/stock/page/stock_balance/stock_balance.js
+++ b/stock/page/stock_balance/stock_balance.js
@@ -99,6 +99,7 @@
var data = wn.report_dump.data["Stock Ledger Entry"];
this.item_warehouse = {};
+ this.serialized_buying_rates = this.get_serialized_buying_rates();
for(var i=0, j=data.length; i<j; i++) {
var sl = data[i];
diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js
index a09cae7..db77fce 100644
--- a/stock/page/stock_home/stock_home.js
+++ b/stock/page/stock_home/stock_home.js
@@ -95,12 +95,6 @@
description: wn._("Change UOM for an Item."),
"doctype": "Stock UOM Replace Utility"
},
- {
- "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool",
- "label": wn._("Sales and Purchase Return Tool"),
- doctype: "Sales and Purchase Return Tool",
- description: wn._("Manage sales or purchase returns")
- },
]
},
{
diff --git a/stock/page/stock_ledger/stock_ledger.js b/stock/page/stock_ledger/stock_ledger.js
index 9af8894..a37ea1c 100644
--- a/stock/page/stock_ledger/stock_ledger.js
+++ b/stock/page/stock_ledger/stock_ledger.js
@@ -155,6 +155,7 @@
// initialize warehouse-item map
this.item_warehouse = {};
+ this.serialized_buying_rates = this.get_serialized_buying_rates();
var from_datetime = dateutil.str_to_obj(me.from_date + " 00:00:00");
var to_datetime = dateutil.str_to_obj(me.to_date + " 23:59:59");
diff --git a/stock/stock_ledger.py b/stock/stock_ledger.py
index 60b5fd4..2480263 100644
--- a/stock/stock_ledger.py
+++ b/stock/stock_ledger.py
@@ -44,7 +44,7 @@
entries_to_fix = get_sle_after_datetime(previous_sle or \
{"item_code": args["item_code"], "warehouse": args["warehouse"]}, for_update=True)
-
+
valuation_method = get_valuation_method(args["item_code"])
for sle in entries_to_fix:
@@ -72,7 +72,7 @@
(qty_after_transaction * valuation_rate) or 0
else:
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
-
+ # print sle.posting_date, sle.actual_qty, sle.incoming_rate, stock_queue, stock_value
# update current sle
webnotes.conn.sql("""update `tabStock Ledger Entry`
set qty_after_transaction=%s, valuation_rate=%s, stock_queue=%s,
@@ -128,7 +128,7 @@
if not args.get("posting_date"):
args["posting_date"] = "1900-01-01"
if not args.get("posting_time"):
- args["posting_time"] = "12:00"
+ args["posting_time"] = "00:00"
return webnotes.conn.sql("""select * from `tabStock Ledger Entry`
where item_code = %%(item_code)s
@@ -214,7 +214,6 @@
def get_fifo_values(qty_after_transaction, sle, stock_queue):
incoming_rate = flt(sle.incoming_rate)
actual_qty = flt(sle.actual_qty)
-
if not stock_queue:
stock_queue.append([0, 0])
diff --git a/stock/utils.py b/stock/utils.py
index 6fac0fd..1406af6 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -163,4 +163,32 @@
elif webnotes.session.user in warehouse_users:
wlist.append([w])
return wlist
-
\ No newline at end of file
+
+def get_buying_amount(item_code, warehouse, qty, voucher_type, voucher_no, voucher_detail_no,
+ stock_ledger_entries, item_sales_bom=None):
+ if item_sales_bom and item_sales_bom.get(item_code):
+ # sales bom item
+ buying_amount = 0.0
+ for bom_item in item_sales_bom[item_code]:
+ buying_amount += _get_buying_amount(voucher_type, voucher_no, "[** No Item Row **]",
+ bom_item.item_code, bom_item.warehouse or warehouse,
+ bom_item.total_qty or (bom_item.qty * qty), stock_ledger_entries)
+ return buying_amount
+ else:
+ # doesn't have sales bom
+ return _get_buying_amount(voucher_type, voucher_no, voucher_detail_no,
+ item_code, warehouse, qty, stock_ledger_entries)
+
+def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, qty,
+ stock_ledger_entries):
+ for i, sle in enumerate(stock_ledger_entries):
+ if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
+ (sle.voucher_detail_no == item_row or (sle.voucher_type != "Stock Reconciliation"
+ and sle.item_code == item_code and sle.warehouse == warehouse and flt(sle.qty) == qty)):
+ previous_stock_value = len(stock_ledger_entries) > i+1 and \
+ flt(stock_ledger_entries[i+1].stock_value) or 0.0
+
+ buying_amount = previous_stock_value - flt(sle.stock_value)
+
+ return buying_amount
+ return 0.0
\ No newline at end of file
diff --git a/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt b/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt
index ba30be4..0aa4d0d 100644
--- a/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt
+++ b/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:31",
+ "creation": "2013-02-22 01:28:05",
"docstatus": 0,
- "modified": "2013-02-04 10:30:18",
+ "modified": "2013-03-07 07:03:23",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -94,6 +94,7 @@
"no_copy": 0,
"oldfieldname": "serial_no",
"oldfieldtype": "Small Text",
+ "print_width": "160px",
"read_only": 1,
"search_index": 0,
"width": "160px"
diff --git a/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt b/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt
index 490eb72..3a95b2c 100644
--- a/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt
+++ b/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:31",
+ "creation": "2013-02-22 01:28:05",
"docstatus": 0,
- "modified": "2013-01-22 14:47:03",
+ "modified": "2013-03-07 07:03:24",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -53,6 +53,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Data",
+ "print_width": "300px",
"read_only": 1,
"width": "300px"
},
@@ -126,6 +127,7 @@
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"search_index": 1,
"width": "150px"
diff --git a/support/doctype/maintenance_visit_purpose/maintenance_visit_purpose.txt b/support/doctype/maintenance_visit_purpose/maintenance_visit_purpose.txt
index 131076c..694f871 100644
--- a/support/doctype/maintenance_visit_purpose/maintenance_visit_purpose.txt
+++ b/support/doctype/maintenance_visit_purpose/maintenance_visit_purpose.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:31",
+ "creation": "2013-02-22 01:28:06",
"docstatus": 0,
- "modified": "2013-01-22 14:47:03",
+ "modified": "2013-03-07 07:03:24",
"modified_by": "Administrator",
"owner": "ashwini@webnotestech.com"
},
@@ -32,6 +32,7 @@
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Small Text",
+ "print_width": "300px",
"reqd": 1,
"width": "300px"
},
@@ -90,6 +91,7 @@
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "160px",
"read_only": 1,
"report_hide": 1,
"width": "160px"
@@ -104,6 +106,7 @@
"oldfieldname": "prevdoc_detail_docname",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "160px",
"read_only": 1,
"report_hide": 1,
"width": "160px"
@@ -118,6 +121,7 @@
"oldfieldname": "prevdoc_doctype",
"oldfieldtype": "Data",
"print_hide": 1,
+ "print_width": "150px",
"read_only": 1,
"report_hide": 1,
"width": "150px"
diff --git a/utilities/cleanup_data.py b/utilities/cleanup_data.py
index a9cc5c3..ed04a94 100644
--- a/utilities/cleanup_data.py
+++ b/utilities/cleanup_data.py
@@ -20,16 +20,14 @@
def delete_transactions():
print "Deleting transactions..."
- trans = ['Timesheet','Task','Support Ticket','Stock Reconciliation', 'Stock Ledger Entry', \
- 'Stock Entry','Sales Order','Salary Slip','Sales Invoice','Quotation', 'Quality Inspection', \
- 'Purchase Receipt','Purchase Order','Production Order', 'POS Setting','Period Closing Voucher', \
- 'Purchase Invoice','Maintenance Visit','Maintenance Schedule','Leave Application', \
- 'Leave Allocation', 'Lead', 'Journal Voucher', 'Installation Note','Material Request', \
- 'GL Entry','Expense Claim','Opportunity','Delivery Note','Customer Issue','Bin', \
- 'Authorization Rule','Attendance', 'C-Form', 'Form 16A', 'Lease Agreement', \
- 'Lease Installment', 'TDS Payment', 'TDS Return Acknowledgement', 'Appraisal', \
- 'Installation Note', 'Communication'
- ]
+ trans = ['Timesheet', 'Task', 'Support Ticket', 'Stock Reconciliation', 'Stock Ledger Entry',
+ 'Stock Entry', 'Sales Order', 'Salary Slip','Sales Invoice', 'Quotation',
+ 'Quality Inspection', 'Purchase Receipt', 'Purchase Order', 'Production Order',
+ 'POS Setting', 'Period Closing Voucher', 'Purchase Invoice', 'Maintenance Visit',
+ 'Maintenance Schedule', 'Leave Application', 'Leave Allocation', 'Lead', 'Journal Voucher',
+ 'Installation Note', 'Material Request', 'GL Entry', 'Expense Claim', 'Opportunity',
+ 'Delivery Note', 'Customer Issue', 'Bin', 'Authorization Rule', 'Attendance', 'C-Form',
+ 'Appraisal', 'Installation Note', 'Communication']
for d in trans:
for t in webnotes.conn.sql("select options from tabDocField where parent='%s' and fieldtype='Table'" % d):
webnotes.conn.sql("delete from `tab%s`" % (t))
@@ -41,55 +39,55 @@
def delete_masters():
print "Deleting masters...."
masters = {
- 'Workstation':['Default Workstation'],
- 'Warehouse Type':['Default Warehouse Type', 'Fixed Asset', 'Rejected', 'Reserved',
+ 'Workstation': ['Default Workstation'],
+ 'Warehouse Type': ['Default Warehouse Type', 'Fixed Asset', 'Rejected', 'Reserved',
'Sample', 'Stores', 'WIP Warehouse'],
- 'Warehouse':['Default Warehouse'],
- 'UOM':['Kg', 'Mtr', 'Box', 'Ltr', 'Nos', 'Ft', 'Pair', 'Set'],
- 'Territory':['All Territories', 'Default Territory'],
- 'Terms and Conditions':'',
- 'Tag':'',
- 'Supplier Type':['Default Supplier Type'],
- 'Supplier':'',
- 'Serial No':'',
- 'Sales Person':['All Sales Persons'],
- 'Sales Partner':'',
- 'Sales BOM':'',
- 'Salary Structure':'',
- 'Purchase Taxes and Charges Master':'',
- 'Project':'',
- 'Print Heading':'',
- 'Price List':['Default Price List'],
- 'Sales Taxes and Charges Master':'',
- 'Letter Head':'',
- 'Leave Type':['Leave Without Pay', 'Privilege Leave', 'Casual Leave', 'PL', 'CL', 'LWP',
+ 'Warehouse': ['Default Warehouse'],
+ 'UOM': ['Kg', 'Mtr', 'Box', 'Ltr', 'Nos', 'Ft', 'Pair', 'Set'],
+ 'Territory': ['All Territories', 'Default Territory'],
+ 'Terms and Conditions': '',
+ 'Tag': '',
+ 'Supplier Type': ['Default Supplier Type'],
+ 'Supplier': '',
+ 'Serial No': '',
+ 'Sales Person': ['All Sales Persons'],
+ 'Sales Partner': '',
+ 'Sales BOM': '',
+ 'Salary Structure': '',
+ 'Purchase Taxes and Charges Master': '',
+ 'Project': '',
+ 'Print Heading': '',
+ 'Price List': ['Default Price List'],
+ 'Sales Taxes and Charges Master': '',
+ 'Letter Head': '',
+ 'Leave Type': ['Leave Without Pay', 'Privilege Leave', 'Casual Leave', 'PL', 'CL', 'LWP',
'Compensatory Off', 'Sick Leave'],
- 'Appraisal Template':'',
- 'Item Group':['All Item Groups', 'Default'],
- 'Item':'',
- 'Holiday List':'',
- 'Grade':'',
- 'Feed':'',
- 'Expense Claim Type':['Travel', 'Medical', 'Calls', 'Food', 'Others'],
- 'Event':'',
- 'Employment Type':'',
- 'Employee':'',
- 'Earning Type':['Basic', 'Conveyance', 'House Rent Allowance', 'Dearness Allowance',
+ 'Appraisal Template': '',
+ 'Item Group': ['All Item Groups', 'Default'],
+ 'Item': '',
+ 'Holiday List': '',
+ 'Grade': '',
+ 'Feed': '',
+ 'Expense Claim Type': ['Travel', 'Medical', 'Calls', 'Food', 'Others'],
+ 'Event': '',
+ 'Employment Type': '',
+ 'Employee': '',
+ 'Earning Type': ['Basic', 'Conveyance', 'House Rent Allowance', 'Dearness Allowance',
'Medical Allowance', 'Telephone'],
- 'Designation':'',
- 'Department':'',
- 'Deduction Type':['Income Tax', 'Professional Tax', 'Provident Fund', 'Leave Deduction'],
- 'Customer Group':['All Customer Groups', 'Default Customer Group'],
- 'Customer':'',
- 'Cost Center':'',
- 'Contact':'',
- 'Campaign':'',
- 'Budget Distribution':'',
- 'Brand':'',
- 'Branch':'',
- 'Batch':'',
- 'Appraisal':'',
- 'Account':'',
+ 'Designation': '',
+ 'Department': '',
+ 'Deduction Type': ['Income Tax', 'Professional Tax', 'Provident Fund', 'Leave Deduction'],
+ 'Customer Group': ['All Customer Groups', 'Default Customer Group'],
+ 'Customer': '',
+ 'Cost Center': '',
+ 'Contact': '',
+ 'Campaign': '',
+ 'Budget Distribution': '',
+ 'Brand': '',
+ 'Branch': '',
+ 'Batch': '',
+ 'Appraisal': '',
+ 'Account': '',
'BOM': ''
}
for d in masters.keys():
@@ -115,40 +113,40 @@
def reset_transaction_series():
webnotes.conn.sql("""update tabSeries set current = 0 where name in
('JV', 'INV', 'BILL', 'SO', 'DN', 'PO', 'LEAD', 'ENQUIRY', 'ENQ', 'CI',
- 'IN', 'PS', 'IDT', 'QAI', 'QTN', 'STE', 'SQTN', 'SUP', 'TDSP', 'SR',
+ 'IN', 'PS', 'IDT', 'QAI', 'QTN', 'STE', 'SQTN', 'SUP', 'SR',
'POS', 'LAP', 'LAL', 'EXP')""")
print "Series updated"
def delete_main_masters():
- main_masters = ['Fiscal Year','Company', 'DefaultValue']
+ main_masters = ['Fiscal Year', 'Company', 'DefaultValue']
for d in main_masters:
for t in webnotes.conn.sql("select options from tabDocField where parent='%s' and fieldtype='Table'" % d):
webnotes.conn.sql("delete from `tab%s`" % (t))
webnotes.conn.sql("delete from `tab%s`" % (d))
print "Deleted " + d
-
-
def reset_global_defaults():
flds = {
- 'default_company': '',
- 'default_currency': '',
- 'current_fiscal_year': '',
+ 'default_company': None,
+ 'default_currency': None,
+ 'current_fiscal_year': None,
'date_format': 'dd-mm-yyyy',
- 'sms_sender_name': '',
+ 'sms_sender_name': None,
'default_item_group': 'Default',
'default_stock_uom': 'Nos',
'default_valuation_method': 'FIFO',
'default_warehouse_type': 'Default Warehouse Type',
- 'tolerance': '',
- 'acc_frozen_upto': '',
- 'bde_auth_role': '',
- 'credit_controller': '',
+ 'tolerance': None,
+ 'acc_frozen_upto': None,
+ 'bde_auth_role': None,
+ 'credit_controller': None,
'default_customer_group': 'Default Customer Group',
'default_territory': 'Default',
'default_price_list': 'Standard',
- 'default_supplier_type': 'Default Supplier Type'
+ 'default_supplier_type': 'Default Supplier Type',
+ 'hide_currency_symbol': None,
+ 'default_price_list_currency': None,
}
from webnotes.model.code import get_obj
diff --git a/utilities/doctype/gl_mapper_detail/gl_mapper_detail.txt b/utilities/doctype/gl_mapper_detail/gl_mapper_detail.txt
index bd1ecd6..079a4a1 100644
--- a/utilities/doctype/gl_mapper_detail/gl_mapper_detail.txt
+++ b/utilities/doctype/gl_mapper_detail/gl_mapper_detail.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:46",
+ "creation": "2013-02-22 01:28:07",
"docstatus": 0,
- "modified": "2012-03-27 14:36:46",
+ "modified": "2013-03-07 07:03:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -11,10 +11,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Utilities",
- "name": "__common__",
- "section_style": "Tray",
- "show_in_menu": 0,
- "version": 4
+ "name": "__common__"
},
{
"doctype": "DocField",
diff --git a/utilities/doctype/sms_receiver/sms_receiver.txt b/utilities/doctype/sms_receiver/sms_receiver.txt
index 4e0831c..1075d21 100644
--- a/utilities/doctype/sms_receiver/sms_receiver.txt
+++ b/utilities/doctype/sms_receiver/sms_receiver.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:47",
+ "creation": "2013-02-22 01:28:07",
"docstatus": 0,
- "modified": "2012-03-27 14:36:47",
+ "modified": "2013-03-07 07:03:32",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,9 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Utilities",
- "name": "__common__",
- "section_style": "Tray",
- "version": 2
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -39,6 +37,7 @@
"fieldname": "receiver_name",
"label": "Receiver Name",
"oldfieldname": "receiver_name",
+ "print_width": "350px",
"width": "350px"
},
{
@@ -46,6 +45,7 @@
"fieldname": "mobile_no",
"label": "Mobile No",
"oldfieldname": "mobile_no",
+ "print_width": "200px",
"reqd": 1,
"width": "200px"
}
diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py
index 61486c5..2dc8c6a 100644
--- a/utilities/transaction_base.py
+++ b/utilities/transaction_base.py
@@ -16,7 +16,7 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import load_json, cstr, flt
+from webnotes.utils import load_json, cstr, flt, now_datetime
from webnotes.model.doc import addchild
from webnotes.model.controller import DocListController
@@ -153,7 +153,7 @@
# Get Lead Details
# -----------------------
def get_lead_details(self, name):
- details = webnotes.conn.sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, territory, contact_no, mobile_no, email_id, company_name from `tabLead` where name = '%s'" %(name), as_dict = 1)
+ details = webnotes.conn.sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, territory, phone, mobile_no, email_id, company_name from `tabLead` where name = '%s'" %(name), as_dict = 1)
extract = lambda x: details and details[0] and details[0].get(x,'') or ''
address_fields = [('','address_line1'),('\n','address_line2'),('\n','city'),(' ','pincode'),('\n','state'),('\n','country'),('\nPhone: ','contact_no')]
@@ -246,4 +246,8 @@
[d.update({"doctype":"Communication"}) for d in comm_list]
self.doclist.extend(webnotes.doclist([webnotes.doc(fielddata=d) \
- for d in comm_list]))
\ No newline at end of file
+ for d in comm_list]))
+
+ def validate_posting_time(self):
+ if not self.doc.posting_time:
+ self.doc.posting_time = now_datetime().strftime('%H:%M:%S')
\ No newline at end of file
diff --git a/website/css/website.css b/website/css/website.css
index 956f22e..dc5b967 100644
--- a/website/css/website.css
+++ b/website/css/website.css
@@ -1,17 +1,12 @@
div.outer {
- -moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
- -webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
- box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
- background-color: #fff;
- border-radius: 5px;
- padding: 20px;
- margin: 30px -20px 10px -20px;
+ padding: 30px;
+ margin: 30px -30px 10px -30px;
min-height: 400px;
overflow: hidden;
}
.outer .navbar {
- margin: -20px -20px 10px -20px;
+ margin: -30px -30px 10px -30px;
}
footer {
@@ -24,6 +19,8 @@
border: 0px;
border-bottom: 1px solid #ddd;
border-radius: 0px;
+ padding-right: 30px;
+ padding-left: 30px;
}
p, li {
@@ -98,6 +95,18 @@
width: 30px;
}
+.avatar-medium {
+ margin-right: 5px;
+ width: 48px;
+ height: 48px;
+ border-radius: 48px;
+ -moz-border-radius: 48px;
+ -webkit-border-radius: 48px;
+}
+.avatar-medium img {
+ width: 48px;
+}
+
.avatar-large {
margin-right: 10px;
width: 72px;
@@ -121,5 +130,3 @@
.avatar-x-large img {
width: 100px;
}
-
-/* */
\ No newline at end of file
diff --git a/website/doctype/about_us_settings/about_us_settings.py b/website/doctype/about_us_settings/about_us_settings.py
index 6c404f1..e291aa8 100644
--- a/website/doctype/about_us_settings/about_us_settings.py
+++ b/website/doctype/about_us_settings/about_us_settings.py
@@ -7,16 +7,16 @@
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
-
- def onload(self):
- """load employee"""
- emp_list = []
- for d in self.doclist.get({"doctype":"About Us Team Member"}):
- emp = webnotes.doc("Employee", d.employee)
- emp.image = url_for_website(emp.image)
- emp_list.append(emp)
- self.doclist += emp_list
-
+
def on_update(self):
from website.utils import clear_cache
- clear_cache("about")
\ No newline at end of file
+ clear_cache("about")
+
+def get_args():
+ obj = webnotes.get_obj("About Us Settings")
+ for d in obj.doclist.get({"doctype":"About Us Team Member"}):
+ if not "/" in d.image_link:
+ d.image_link = "files/" + d.image_link
+ return {
+ "obj": obj
+ }
\ No newline at end of file
diff --git a/website/doctype/about_us_settings/about_us_settings.txt b/website/doctype/about_us_settings/about_us_settings.txt
index a42d2f3..b846d2b 100644
--- a/website/doctype/about_us_settings/about_us_settings.txt
+++ b/website/doctype/about_us_settings/about_us_settings.txt
@@ -1,12 +1,13 @@
[
{
- "creation": "2013-01-10 16:34:32",
+ "creation": "2013-03-07 15:53:15",
"docstatus": 0,
- "modified": "2013-01-22 14:12:16",
+ "modified": "2013-03-12 14:48:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
+ "allow_attach": 1,
"description": "Settings for the About Us Page",
"doctype": "DocType",
"document_type": "Master",
@@ -31,7 +32,7 @@
"parenttype": "DocType",
"permlevel": 0,
"read": 1,
- "report": 1,
+ "report": 0,
"role": "Website Manager",
"submit": 0,
"write": 1
@@ -45,7 +46,7 @@
"fieldname": "help",
"fieldtype": "HTML",
"label": "Help",
- "options": "<div class=\"alert\">Link for About Us Page is \"about.html\"</div>"
+ "options": "<div class=\"alert\">Link for About Us Page is \"/about\"</div>"
},
{
"description": "Introduce your company to the website visitor.",
@@ -102,6 +103,15 @@
"label": "Footer"
},
{
+ "doctype": "DocField",
+ "fieldname": "file_list",
+ "fieldtype": "Text",
+ "hidden": 1,
+ "label": "File List",
+ "no_copy": 1,
+ "print_hide": 1
+ },
+ {
"doctype": "DocPerm"
}
]
\ No newline at end of file
diff --git a/website/doctype/about_us_team_member/about_us_team_member.txt b/website/doctype/about_us_team_member/about_us_team_member.txt
index a68ddcf..b1bf6b3 100644
--- a/website/doctype/about_us_team_member/about_us_team_member.txt
+++ b/website/doctype/about_us_team_member/about_us_team_member.txt
@@ -1,35 +1,51 @@
[
{
- "owner": "Administrator",
+ "creation": "2013-03-07 11:55:11",
"docstatus": 0,
- "creation": "2012-12-27 14:28:45",
+ "modified": "2013-03-12 13:51:02",
"modified_by": "Administrator",
- "modified": "2012-12-27 14:49:44"
+ "owner": "Administrator"
},
{
- "istable": 1,
- "name": "__common__",
"doctype": "DocType",
- "module": "Website"
+ "istable": 1,
+ "module": "Website",
+ "name": "__common__"
},
{
- "parent": "About Us Team Member",
"doctype": "DocField",
"name": "__common__",
- "label": "Employee",
- "width": "300px",
+ "parent": "About Us Team Member",
+ "parentfield": "fields",
"parenttype": "DocType",
- "options": "Employee",
- "fieldname": "employee",
- "fieldtype": "Link",
- "permlevel": 0,
- "parentfield": "fields"
+ "permlevel": 0
},
{
- "name": "About Us Team Member",
- "doctype": "DocType"
+ "doctype": "DocType",
+ "name": "About Us Team Member"
},
{
- "doctype": "DocField"
+ "doctype": "DocField",
+ "fieldname": "full_name",
+ "fieldtype": "Data",
+ "label": "Full Name",
+ "reqd": 1,
+ "width": "150px"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "image_link",
+ "fieldtype": "Select",
+ "label": "Image Link",
+ "options": "attach_files:",
+ "width": "150px"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "bio",
+ "fieldtype": "Small Text",
+ "label": "Bio",
+ "reqd": 1,
+ "width": "200px"
}
]
\ No newline at end of file
diff --git a/website/doctype/blog/__init__.py b/website/doctype/blog/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/website/doctype/blog/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/website/doctype/blog/locale/_messages_doc.json b/website/doctype/blog/locale/_messages_doc.json
deleted file mode 100644
index 90697bd..0000000
--- a/website/doctype/blog/locale/_messages_doc.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
- "Website",
- "Content",
- "Title",
- "Blog Intro",
- "Page Name",
- "Blog",
- "Email Sent",
- "File List",
- "Published",
- "Description for listing page, in plain text, only a couple of lines."
-]
\ No newline at end of file
diff --git a/website/doctype/blog/locale/ar-doc.json b/website/doctype/blog/locale/ar-doc.json
deleted file mode 100644
index 10ecf12..0000000
--- a/website/doctype/blog/locale/ar-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "\u0628\u0644\u0648\u0642",
- "Content": "\u0645\u062d\u062a\u0648\u0649",
- "Email Sent": "\u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a",
- "File List": "\u0645\u0644\u0641 \u0642\u0627\u0626\u0645\u0629",
- "Page Name": "\u0627\u0644\u0635\u0641\u062d\u0629 \u0627\u0633\u0645",
- "Published": "\u0646\u0634\u0631\u062a",
- "Title": "\u0644\u0642\u0628",
- "Website": "\u0627\u0644\u0645\u0648\u0642\u0639"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/de-doc.json b/website/doctype/blog/locale/de-doc.json
deleted file mode 100644
index a4f0013..0000000
--- a/website/doctype/blog/locale/de-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "Blog",
- "Content": "Inhalt",
- "Email Sent": "E-Mail gesendet",
- "File List": "Dateiliste",
- "Page Name": "Page Name",
- "Published": "Ver\u00f6ffentlicht",
- "Title": "Titel",
- "Website": "Webseite"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/es-doc.json b/website/doctype/blog/locale/es-doc.json
deleted file mode 100644
index 727ca12..0000000
--- a/website/doctype/blog/locale/es-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "Blog",
- "Content": "Contenido",
- "Email Sent": "Correo electr\u00f3nico enviado",
- "File List": "Lista de archivos",
- "Page Name": "Nombre p\u00e1gina",
- "Published": "Publicado",
- "Title": "T\u00edtulo",
- "Website": "Sitio web"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/fr-doc.json b/website/doctype/blog/locale/fr-doc.json
deleted file mode 100644
index d30abca..0000000
--- a/website/doctype/blog/locale/fr-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "Blog",
- "Content": "Teneur",
- "Email Sent": "Courriel a \u00e9t\u00e9 envoy\u00e9",
- "File List": "Liste des fichiers",
- "Page Name": "Nom de la page",
- "Published": "Publi\u00e9",
- "Title": "Titre",
- "Website": "Site Web"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/hi-doc.json b/website/doctype/blog/locale/hi-doc.json
deleted file mode 100644
index 5191c3a..0000000
--- a/website/doctype/blog/locale/hi-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "\u092c\u094d\u0932\u0949\u0917",
- "Content": "\u0938\u093e\u092e\u0917\u094d\u0930\u0940",
- "Email Sent": "\u0908\u092e\u0947\u0932 \u092d\u0947\u091c\u093e \u0917\u092f\u093e",
- "File List": "\u092b\u093c\u093e\u0907\u0932 \u0938\u0942\u091a\u0940",
- "Page Name": "\u092a\u0947\u091c \u0915\u093e \u0928\u093e\u092e",
- "Published": "\u092a\u094d\u0930\u0915\u093e\u0936\u093f\u0924",
- "Title": "\u0936\u0940\u0930\u094d\u0937\u0915",
- "Website": "\u0935\u0947\u092c\u0938\u093e\u0907\u091f"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/hr-doc.json b/website/doctype/blog/locale/hr-doc.json
deleted file mode 100644
index b77e5ac..0000000
--- a/website/doctype/blog/locale/hr-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "Blog",
- "Content": "Sadr\u017eaj",
- "Email Sent": "E-mail poslan",
- "File List": "Popis datoteka",
- "Page Name": "Stranica Ime",
- "Published": "Objavljen",
- "Title": "Naslov",
- "Website": "Website"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/nl-doc.json b/website/doctype/blog/locale/nl-doc.json
deleted file mode 100644
index 08aca3d..0000000
--- a/website/doctype/blog/locale/nl-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "Blog",
- "Content": "Inhoud",
- "Email Sent": "E-mail verzonden",
- "File List": "File List",
- "Page Name": "Page Name",
- "Published": "Gepubliceerd",
- "Title": "Titel",
- "Website": "Website"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/pt-BR-doc.json b/website/doctype/blog/locale/pt-BR-doc.json
deleted file mode 100644
index b30e539..0000000
--- a/website/doctype/blog/locale/pt-BR-doc.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "Blog": "Blog",
- "Blog Intro": "Blog Intro",
- "Content": "Conte\u00fado",
- "Description for listing page, in plain text, only a couple of lines.": "Descri\u00e7\u00e3o p\u00e1gina de listagem, em texto simples, apenas um par de linhas.",
- "Email Sent": "E-mail enviado",
- "File List": "Lista de Arquivos",
- "Page Name": "Nome da P\u00e1gina",
- "Published": "Publicado",
- "Title": "T\u00edtulo",
- "Website": "Site"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/pt-doc.json b/website/doctype/blog/locale/pt-doc.json
deleted file mode 100644
index 39bc7d4..0000000
--- a/website/doctype/blog/locale/pt-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "Blog",
- "Content": "Conte\u00fado",
- "Email Sent": "E-mail enviado",
- "File List": "Lista de Arquivos",
- "Page Name": "Nome da P\u00e1gina",
- "Published": "Publicado",
- "Title": "T\u00edtulo",
- "Website": "Site"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/sr-doc.json b/website/doctype/blog/locale/sr-doc.json
deleted file mode 100644
index 2b67eec..0000000
--- a/website/doctype/blog/locale/sr-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "\u0411\u043b\u043e\u0433",
- "Content": "\u0421\u0430\u0434\u0440\u0436\u0438\u043d\u0430",
- "Email Sent": "\u0415\u043c\u0430\u0438\u043b \u0421\u0435\u043d\u0442",
- "File List": "\u0424\u0438\u043b\u0435 \u041b\u0438\u0441\u0442",
- "Page Name": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0418\u043c\u0435",
- "Published": "\u041e\u0431\u0458\u0430\u0432\u0459\u0435\u043d",
- "Title": "\u041d\u0430\u0441\u043b\u043e\u0432",
- "Website": "\u0412\u0435\u0431\u0441\u0430\u0458\u0442"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/ta-doc.json b/website/doctype/blog/locale/ta-doc.json
deleted file mode 100644
index c34c192..0000000
--- a/website/doctype/blog/locale/ta-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "\u0bb5\u0bb2\u0bc8\u0baa\u0bcd\u0baa\u0ba4\u0bbf\u0bb5\u0bc1",
- "Content": "\u0b89\u0bb3\u0bcd\u0bb3\u0b9f\u0b95\u0bcd\u0b95\u0bae\u0bcd",
- "Email Sent": "\u0bae\u0bbf\u0ba9\u0bcd\u0ba9\u0b9e\u0bcd\u0b9a\u0bb2\u0bcd \u0b85\u0ba9\u0bc1\u0baa\u0bcd\u0baa\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1",
- "File List": "\u0b95\u0bc7\u0bbe\u0baa\u0bcd\u0baa\u0bc1 \u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bcd",
- "Page Name": "\u0baa\u0b95\u0bcd\u0b95\u0bae\u0bcd \u0baa\u0bc6\u0baf\u0bb0\u0bcd",
- "Published": "\u0bb5\u0bc6\u0bb3\u0bbf\u0baf\u0bbf\u0b9f\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f",
- "Title": "\u0ba4\u0bb2\u0bc8\u0baa\u0bcd\u0baa\u0bc1",
- "Website": "\u0b87\u0ba3\u0bc8\u0baf\u0ba4\u0bb3\u0bae\u0bcd"
-}
\ No newline at end of file
diff --git a/website/doctype/blog/locale/th-doc.json b/website/doctype/blog/locale/th-doc.json
deleted file mode 100644
index e043a41..0000000
--- a/website/doctype/blog/locale/th-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Blog": "\u0e1a\u0e25\u0e47\u0e2d\u0e01",
- "Content": "\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32",
- "Email Sent": "\u0e2d\u0e35\u0e40\u0e21\u0e25\u0e17\u0e35\u0e48\u0e2a\u0e48\u0e07",
- "File List": "\u0e23\u0e32\u0e22\u0e0a\u0e37\u0e48\u0e2d\u0e44\u0e1f\u0e25\u0e4c",
- "Page Name": "\u0e0a\u0e37\u0e48\u0e2d\u0e40\u0e1e\u0e08",
- "Published": "\u0e40\u0e1c\u0e22\u0e41\u0e1e\u0e23\u0e48",
- "Title": "\u0e0a\u0e37\u0e48\u0e2d\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07",
- "Website": "\u0e40\u0e27\u0e47\u0e1a\u0e44\u0e0b\u0e15\u0e4c"
-}
\ No newline at end of file
diff --git a/website/doctype/blog_category/__init__.py b/website/doctype/blog_category/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/website/doctype/blog_category/__init__.py
diff --git a/website/doctype/blog_category/blog_category.py b/website/doctype/blog_category/blog_category.py
new file mode 100644
index 0000000..c8c369c
--- /dev/null
+++ b/website/doctype/blog_category/blog_category.py
@@ -0,0 +1,14 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+class DocType:
+ def __init__(self, d, dl):
+ self.doc, self.doclist = d, dl
+
+ def on_update(self):
+ # for blog footer
+ from website.utils import clear_cache
+ clear_cache()
+
\ No newline at end of file
diff --git a/website/doctype/blog_category/blog_category.txt b/website/doctype/blog_category/blog_category.txt
new file mode 100644
index 0000000..cf8cad6
--- /dev/null
+++ b/website/doctype/blog_category/blog_category.txt
@@ -0,0 +1,51 @@
+[
+ {
+ "creation": "2013-03-08 09:41:11",
+ "docstatus": 0,
+ "modified": "2013-03-08 09:41:11",
+ "modified_by": "Administrator",
+ "owner": "Administrator"
+ },
+ {
+ "autoname": "field:category_name",
+ "doctype": "DocType",
+ "document_type": "Master",
+ "module": "Website",
+ "name": "__common__"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "category_name",
+ "fieldtype": "Data",
+ "label": "Category Name",
+ "name": "__common__",
+ "parent": "Blog Category",
+ "parentfield": "fields",
+ "parenttype": "DocType",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "cancel": 1,
+ "create": 1,
+ "doctype": "DocPerm",
+ "name": "__common__",
+ "parent": "Blog Category",
+ "parentfield": "permissions",
+ "parenttype": "DocType",
+ "permlevel": 0,
+ "read": 1,
+ "role": "Website Manager",
+ "write": 1
+ },
+ {
+ "doctype": "DocType",
+ "name": "Blog Category"
+ },
+ {
+ "doctype": "DocField"
+ },
+ {
+ "doctype": "DocPerm"
+ }
+]
\ No newline at end of file
diff --git a/website/doctype/blog_post/__init__.py b/website/doctype/blog_post/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/website/doctype/blog_post/__init__.py
diff --git a/website/doctype/blog/blog.js b/website/doctype/blog_post/blog_post.js
similarity index 100%
rename from website/doctype/blog/blog.js
rename to website/doctype/blog_post/blog_post.js
diff --git a/website/doctype/blog/blog.py b/website/doctype/blog_post/blog_post.py
similarity index 67%
rename from website/doctype/blog/blog.py
rename to website/doctype/blog_post/blog_post.py
index cfc0ca6..ff6cc99 100644
--- a/website/doctype/blog/blog.py
+++ b/website/doctype/blog_post/blog_post.py
@@ -18,6 +18,7 @@
import webnotes
import website.utils
+from webnotes import _
class DocType:
def __init__(self, d, dl):
@@ -27,9 +28,18 @@
from website.utils import page_name
self.doc.name = page_name(self.doc.title)
+ def validate(self):
+ if self.doc.blog_intro:
+ self.doc.blog_intro = self.doc.blog_intro[:140]
+
+ # update posts
+ webnotes.conn.sql("""update tabBlogger set posts=(select count(*) from `tabBlog Post`
+ where ifnull(blogger,'')=tabBlogger.name)
+ where name=%s""", self.doc.blogger)
+
def on_update(self):
- from website.utils import update_page_name
- update_page_name(self.doc, self.doc.title)
+ website.utils.update_page_name(self.doc, self.doc.title)
+ website.utils.delete_page_cache("writers")
def send_emails(self):
"""send emails to subscribers"""
@@ -40,8 +50,8 @@
import webnotes.utils
# get leads that are subscribed to the blog
- recipients = [e[0] for e in webnotes.conn.sql("""select distinct email_id from tabLead where
- ifnull(blog_subscriber,0)=1""")]
+ recipients = [e[0] for e in webnotes.conn.sql("""select distinct email_id from
+ tabLead where ifnull(blog_subscriber,0)=1""")]
# make heading as link
content = '<h2><a href="%s/%s.html">%s</a></h2>\n\n%s' % (webnotes.utils.get_request_site_address(),
@@ -64,12 +74,28 @@
# temp fields
from webnotes.utils import global_date_format, get_fullname
self.doc.full_name = get_fullname(self.doc.owner)
- self.doc.updated = global_date_format(self.doc.creation)
+ self.doc.updated = global_date_format(self.doc.published_on)
self.doc.content_html = self.doc.content
+ if self.doc.blogger:
+ self.doc.blogger_info = webnotes.doc("Blogger", self.doc.blogger).fields
+ if self.doc.blogger_info.avatar and not "/" in self.doc.blogger_info.avatar:
+ self.doc.blogger_info.avatar = "files/" + self.doc.blogger_info.avatar
+
+ self.doc.description = self.doc.blog_intro or self.doc.content[:140]
+
+ self.doc.categories = webnotes.conn.sql_list("select name from `tabBlog Category` order by name")
+
+ self.doc.texts = {
+ "comments": _("Comments"),
+ "first_comment": _("Be the first one to comment"),
+ "add_comment": _("Add Comment"),
+ "submit": _("Submit"),
+ "all_posts_by": _("All posts by"),
+ }
comment_list = webnotes.conn.sql("""\
select comment, comment_by_fullname, creation
- from `tabComment` where comment_doctype="Blog"
+ from `tabComment` where comment_doctype="Blog Post"
and comment_docname=%s order by creation""", self.doc.name, as_dict=1)
self.doc.comment_list = comment_list or []
diff --git a/website/doctype/blog/blog.txt b/website/doctype/blog_post/blog_post.txt
similarity index 66%
rename from website/doctype/blog/blog.txt
rename to website/doctype/blog_post/blog_post.txt
index af9606a..480bca4 100644
--- a/website/doctype/blog/blog.txt
+++ b/website/doctype/blog_post/blog_post.txt
@@ -1,13 +1,14 @@
[
{
- "creation": "2013-01-25 11:35:09",
+ "creation": "2013-03-08 11:36:50",
"docstatus": 0,
- "modified": "2013-02-21 16:54:04",
+ "modified": "2013-03-11 15:23:21",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
+ "allow_import": 1,
"doctype": "DocType",
"max_attachments": 5,
"module": "Website",
@@ -16,7 +17,7 @@
{
"doctype": "DocField",
"name": "__common__",
- "parent": "Blog",
+ "parent": "Blog Post",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
@@ -24,7 +25,7 @@
{
"doctype": "DocPerm",
"name": "__common__",
- "parent": "Blog",
+ "parent": "Blog Post",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
@@ -34,7 +35,7 @@
},
{
"doctype": "DocType",
- "name": "Blog"
+ "name": "Blog Post"
},
{
"doctype": "DocField",
@@ -50,18 +51,50 @@
"label": "Published"
},
{
- "description": "Description for listing page, in plain text, only a couple of lines.",
+ "doctype": "DocField",
+ "fieldname": "published_on",
+ "fieldtype": "Date",
+ "label": "Published On"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "blogger",
+ "fieldtype": "Link",
+ "label": "Blogger",
+ "options": "Blogger",
+ "reqd": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "blog_category",
+ "fieldtype": "Link",
+ "label": "Blog Category",
+ "options": "Blog Category"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break"
+ },
+ {
+ "description": "Description for listing page, in plain text, only a couple of lines. (max 140 characters)",
"doctype": "DocField",
"fieldname": "blog_intro",
"fieldtype": "Small Text",
- "label": "Blog Intro"
+ "label": "Blog Intro",
+ "reqd": 1
},
{
"doctype": "DocField",
"fieldname": "content",
"fieldtype": "Text Editor",
"label": "Content",
- "reqd": 0
+ "reqd": 1
},
{
"doctype": "DocField",
diff --git a/website/doctype/blog_settings/__init__.py b/website/doctype/blog_settings/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/website/doctype/blog_settings/__init__.py
diff --git a/website/doctype/blog_settings/blog_settings.py b/website/doctype/blog_settings/blog_settings.py
new file mode 100644
index 0000000..928aa9f
--- /dev/null
+++ b/website/doctype/blog_settings/blog_settings.py
@@ -0,0 +1,8 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+class DocType:
+ def __init__(self, d, dl):
+ self.doc, self.doclist = d, dl
\ No newline at end of file
diff --git a/website/doctype/blog_settings/blog_settings.txt b/website/doctype/blog_settings/blog_settings.txt
new file mode 100644
index 0000000..09740eb
--- /dev/null
+++ b/website/doctype/blog_settings/blog_settings.txt
@@ -0,0 +1,61 @@
+[
+ {
+ "creation": "2013-03-11 17:48:16",
+ "docstatus": 0,
+ "modified": "2013-03-11 17:48:16",
+ "modified_by": "Administrator",
+ "owner": "Administrator"
+ },
+ {
+ "description": "Blog Settings",
+ "doctype": "DocType",
+ "issingle": 1,
+ "module": "Website",
+ "name": "__common__"
+ },
+ {
+ "doctype": "DocField",
+ "name": "__common__",
+ "parent": "Blog Settings",
+ "parentfield": "fields",
+ "parenttype": "DocType",
+ "permlevel": 0
+ },
+ {
+ "create": 1,
+ "doctype": "DocPerm",
+ "name": "__common__",
+ "parent": "Blog Settings",
+ "parentfield": "permissions",
+ "parenttype": "DocType",
+ "permlevel": 0,
+ "read": 1,
+ "role": "Website Manager",
+ "write": 1
+ },
+ {
+ "doctype": "DocType",
+ "name": "Blog Settings"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "blog_title",
+ "fieldtype": "Data",
+ "label": "Blog Title"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "blog_introduction",
+ "fieldtype": "Small Text",
+ "label": "Blog Introduction"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "writers_introduction",
+ "fieldtype": "Small Text",
+ "label": "Writers Introduction"
+ },
+ {
+ "doctype": "DocPerm"
+ }
+]
\ No newline at end of file
diff --git a/website/doctype/blogger/__init__.py b/website/doctype/blogger/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/website/doctype/blogger/__init__.py
diff --git a/website/doctype/blogger/blogger.py b/website/doctype/blogger/blogger.py
new file mode 100644
index 0000000..a16867d
--- /dev/null
+++ b/website/doctype/blogger/blogger.py
@@ -0,0 +1,22 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+class DocType:
+ def __init__(self, d, dl):
+ self.doc, self.doclist = d, dl
+
+ def on_update(self):
+ "if profile is set, then update all older blogs"
+
+ from website.helpers.blog import clear_blog_cache
+ clear_blog_cache()
+
+ if self.doc.profile:
+ for blog in webnotes.conn.sql_list("""select name from `tabBlog Post` where owner=%s
+ and ifnull(blogger,'')=''""", self.doc.profile):
+ b = webnotes.bean("Blog Post", blog)
+ b.doc.blogger = self.doc.name
+ b.save()
+
diff --git a/website/doctype/blogger/blogger.txt b/website/doctype/blogger/blogger.txt
new file mode 100644
index 0000000..7f741c5
--- /dev/null
+++ b/website/doctype/blogger/blogger.txt
@@ -0,0 +1,102 @@
+[
+ {
+ "creation": "2013-03-08 11:36:52",
+ "docstatus": 0,
+ "modified": "2013-03-11 14:00:37",
+ "modified_by": "Administrator",
+ "owner": "Administrator"
+ },
+ {
+ "allow_attach": 1,
+ "autoname": "field:short_name",
+ "description": "Profile of a Blogger",
+ "doctype": "DocType",
+ "document_type": "Master",
+ "max_attachments": 1,
+ "module": "Website",
+ "name": "__common__"
+ },
+ {
+ "doctype": "DocField",
+ "name": "__common__",
+ "parent": "Blogger",
+ "parentfield": "fields",
+ "parenttype": "DocType",
+ "permlevel": 0
+ },
+ {
+ "doctype": "DocPerm",
+ "name": "__common__",
+ "parent": "Blogger",
+ "parentfield": "permissions",
+ "parenttype": "DocType",
+ "permlevel": 0,
+ "read": 1,
+ "write": 1
+ },
+ {
+ "doctype": "DocType",
+ "name": "Blogger"
+ },
+ {
+ "description": "Will be used in url (usually first name).",
+ "doctype": "DocField",
+ "fieldname": "short_name",
+ "fieldtype": "Data",
+ "label": "Short Name",
+ "reqd": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "full_name",
+ "fieldtype": "Data",
+ "label": "Full Name",
+ "reqd": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "profile",
+ "fieldtype": "Link",
+ "label": "Profile",
+ "options": "Profile"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "bio",
+ "fieldtype": "Small Text",
+ "label": "Bio"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "avatar",
+ "fieldtype": "Select",
+ "label": "Avatar",
+ "options": "attach_files:"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "posts",
+ "fieldtype": "Int",
+ "label": "Posts",
+ "read_only": 1
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "file_list",
+ "fieldtype": "Text",
+ "hidden": 1,
+ "label": "File List",
+ "no_copy": 1,
+ "print_hide": 1
+ },
+ {
+ "create": 1,
+ "doctype": "DocPerm",
+ "role": "Website Manager"
+ },
+ {
+ "doctype": "DocPerm",
+ "match": "owner:profile",
+ "role": "Blogger"
+ }
+]
\ No newline at end of file
diff --git a/website/doctype/company_history/company_history.txt b/website/doctype/company_history/company_history.txt
index 64fe6c2..544845d 100644
--- a/website/doctype/company_history/company_history.txt
+++ b/website/doctype/company_history/company_history.txt
@@ -1,40 +1,41 @@
[
{
- "owner": "Administrator",
+ "creation": "2013-02-22 01:28:08",
"docstatus": 0,
- "creation": "2012-12-27 14:25:38",
+ "modified": "2013-03-07 07:03:19",
"modified_by": "Administrator",
- "modified": "2012-12-27 14:25:38"
+ "owner": "Administrator"
},
{
- "istable": 1,
- "name": "__common__",
"doctype": "DocType",
- "module": "Website"
+ "istable": 1,
+ "module": "Website",
+ "name": "__common__"
},
{
+ "doctype": "DocField",
"name": "__common__",
"parent": "Company History",
- "doctype": "DocField",
+ "parentfield": "fields",
"parenttype": "DocType",
- "permlevel": 0,
- "parentfield": "fields"
+ "permlevel": 0
},
{
- "name": "Company History",
- "doctype": "DocType"
+ "doctype": "DocType",
+ "name": "Company History"
},
{
"doctype": "DocField",
- "label": "Year",
"fieldname": "year",
- "fieldtype": "Data"
+ "fieldtype": "Data",
+ "label": "Year"
},
{
"doctype": "DocField",
- "label": "Highlight",
- "width": "300px",
"fieldname": "highlight",
- "fieldtype": "Text"
+ "fieldtype": "Text",
+ "label": "Highlight",
+ "print_width": "300px",
+ "width": "300px"
}
]
\ No newline at end of file
diff --git a/website/doctype/contact_us_settings/contact_us_settings.txt b/website/doctype/contact_us_settings/contact_us_settings.txt
index 1bc7b05..ef2da02 100644
--- a/website/doctype/contact_us_settings/contact_us_settings.txt
+++ b/website/doctype/contact_us_settings/contact_us_settings.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-12-27 19:04:50",
+ "creation": "2013-02-21 20:12:42",
"docstatus": 0,
- "modified": "2013-02-21 16:49:33",
+ "modified": "2013-03-12 14:49:01",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -44,7 +44,7 @@
"fieldname": "help",
"fieldtype": "HTML",
"label": "Help",
- "options": "<div class=\"alert\">Link for Contact Page is \"contact.html\"</div>"
+ "options": "<div class=\"alert\">Link for Contact Page is \"/contact\"</div>"
},
{
"description": "Address to be displayed on the Contact Page",
diff --git a/website/doctype/related_page/related_page.txt b/website/doctype/related_page/related_page.txt
index a4a0983..2f21cbd 100644
--- a/website/doctype/related_page/related_page.txt
+++ b/website/doctype/related_page/related_page.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-03-27 14:36:48",
+ "creation": "2013-02-22 01:28:08",
"docstatus": 0,
- "modified": "2012-03-27 14:36:48",
+ "modified": "2013-03-07 07:03:30",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Website",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 3
+ "name": "__common__"
},
{
"doctype": "DocField",
diff --git a/website/doctype/style_settings/custom_template.css b/website/doctype/style_settings/custom_template.css
index 9009bbe..712c748 100644
--- a/website/doctype/style_settings/custom_template.css
+++ b/website/doctype/style_settings/custom_template.css
@@ -1,3 +1,7 @@
+{% if doc.at_import %}
+{{ doc.at_import }}
+{% endif %}
+
body {
{% if doc.background_image %}
background: url("../files/{{ doc.background_image }}") repeat;
@@ -7,22 +11,232 @@
{% else %}
background-color: #edede7;
{% endif %}
-{% if doc.font %}
- font-family: '{{ doc.font }}', Verdana, Sans !important;
+{% if doc.font or doc.google_web_font_for_text %}
+ font-family: '{{ doc.google_web_font_for_text or doc.font }}', 'Helvetica Neue', Arial, Sans !important;
{% endif %}
-{% if doc.font_size %}
- font-size: {{ doc.font_size }} !important;
-{% endif %}
+ {% if doc.font_size %}font-size: {{ doc.font_size }} !important;{% endif %}
+ {% if doc.page_text %}color: #{{ doc.page_text }};{% endif %}
}
+{% if doc.page_links %}a, a:hover {
+ color: #{{ doc.page_links }};
+}{% endif %}
+
{% if doc.font_size %}
.small {
font-size: {{ doc.small_font_size }} !important;
}
{% endif %}
-{% if doc.heading_font %}
-h1, h2, h3, h4, h5 {
- font-family: '{{ doc.heading_font}}', Arial, 'Helvetica Neue' !important;
-}
+div.outer {
+ background-color: #{{ doc.page_background or "fffffff" }};
+}
+
+{% if doc.google_web_font_for_heading or doc.heading_font %}h1, h2, h3, h4, h5 {
+ font-family: '{{ doc.google_web_font_for_heading or doc.heading_font }}', 'Helvetica Neue', Arial !important;
+}{% endif %}
+
+{% if doc.heading_text_style %}h1, h2, h3, h4, h5 {
+ text-transform: {{ doc.heading_text_style }};
+}{% endif %}
+
+{% if doc.page_headings %}h1, h2, h3, h4, h5 {
+ color: #{{ doc.page_headings }};
+}{% endif %}
+
+{% if doc.page_border %}
+/* Page Border*/
+div.outer {
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
+ -webkibox-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
+}
+{% else %}
+{% if doc.background_color == doc.page_background %}
+div.web-footer {
+ border-top: 1px solid #{{ get_hex_shade(doc.page_background or "ffffff", 15) }};
+ padding-top: 10px;
+}
{% endif %}
+{% endif %}
+
+div.web-footer, div.web-footer a {
+ font-size: 90%;
+ color: #{{ get_hex_shade(doc.background_color or "ffffff", 70) }};
+}
+
+/* Bootstrap Navbar */
+.navbar-inverse .navbar-inner {
+ background-color: #{{ doc.top_bar_background or "444444"}};
+ background-repeat: repeat-x;
+ border-color: transparent;
+ background-image: none;
+}
+
+.navbar-inner {
+ box-shadow: none;
+}
+
+{% if doc.top_bar_background == doc.page_background %}.navbar-inner {
+ border-bottom: 1px solid #{{ get_hex_shade(doc.page_background or "ffffff", 15) }};
+}{% endif %}
+
+.navbar-inverse .brand,
+.navbar-inverse .brand:hover,
+.navbar-inverse .brand:focus,
+.navbar-inverse .nav > li > a {
+ color: #{{ doc.top_bar_foreground or "fffffff"}};
+ text-shadow: none;
+}
+
+.navbar-inverse .nav > li > a:hover,
+.navbar-inverse .nav > li > a:focus {
+ color: #{{ doc.top_bar_background or "0000000"}};
+}
+
+.navbar-inverse .navbar-text {
+ color: #999999;
+}
+
+.navbar-inverse .nav > li > a:focus,
+.navbar-inverse .nav > li > a:hover {
+ color: #{{ doc.top_bar_foreground or "fffffff"}};
+ background-color: transparent;
+}
+
+.navbar-inverse .nav .active > a,
+.navbar-inverse .nav .active > a:hover,
+.navbar-inverse .nav .active > a:focus {
+ color: #{{ doc.top_bar_foreground or "fffffff"}};
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-link {
+ color: #999999;
+}
+
+.navbar-inverse .navbar-link:hover,
+.navbar-inverse .navbar-link:focus {
+ color: #{{ doc.top_bar_foreground or "fffffff"}};
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-static-top .navbar-inner {
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+
+}
+.navbar .nav > .active > a,
+.navbar .nav > .active > a:hover,
+.navbar .nav > .active > a:focus {
+ color: #424242;
+ text-decoration: none;
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret,
+.navbar-inverse .nav li.dropdown > .dropdown-toggle:hover .caret {
+ border-top-color: #{{ doc.top_bar_foreground or "fffffff"}};
+ border-bottom-color: #{{ doc.top_bar_foreground or "fffffff"}};
+}
+
+.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,
+.navbar-inverse .nav li.dropdown.open > .dropdown-toggle:hover .caret {
+ border-top-color: #{{ doc.top_bar_background or "0000000"}};
+ border-bottom-color: #{{ doc.top_bar_background or "0000000"}};
+}
+
+.navbar-inverse .nav li.dropdown.open > .dropdown-toggle {
+ color: #{{ doc.top_bar_background or "0000000"}};
+ background-color: #{{ doc.top_bar_foreground or "fffffff"}};
+}
+
+@media (max-width: 800px) {
+ .navbar-inverse .nav-collapse .nav > li > a,
+ .navbar-inverse .nav-collapse .dropdown-menu a {
+ background-color: #{{ doc.top_bar_background or "0000000"}};
+ color: #{{ doc.top_bar_foreground or "fffffff"}};
+ }
+ .navbar-inverse .nav-collapse .nav > li > a:hover,
+ .navbar-inverse .nav-collapse .dropdown-menu a:hover {
+ background-color: #{{ doc.top_bar_foreground or "fffffff"}};
+ color: #{{ doc.top_bar_background or "0000000"}};
+ }
+
+ .navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {
+ border-top-color: #{{ doc.top_bar_foreground or "fffffff" }};
+ border-bottom-color: #{{ doc.top_bar_foreground or "fffffff" }};
+ }
+
+ .navbar-inverse .nav li.dropdown > .dropdown-toggle:hover .caret {
+ border-top-color: #{{ doc.top_bar_background or "0000000" }};
+ border-bottom-color: #{{ doc.top_bar_background or "0000000" }};
+ }
+
+ .navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,
+ .navbar-inverse .nav li.dropdown.open > .dropdown-toggle:hover .caret {
+ border-top-color: #{{ doc.top_bar_background or "0000000" }};
+ border-bottom-color: #{{ doc.top_bar_background or "0000000" }};
+ }
+
+}
+
+.breadcrumb {
+ background-color: #{{ get_hex_shade(doc.page_background or "ffffff", 10) }};
+}
+
+.breadcrumb > li {
+ text-shadow: none;
+}
+
+.breadcrumb > li > .divider {
+ color: #{{ doc.page_text }};
+}
+
+.breadcrumb > .active {
+ color: #{{ doc.page_text }};
+}
+
+
+.table-striped tbody > tr:nth-child(odd) > td,
+.table-striped tbody > tr:nth-child(odd) > th {
+ background-color: #{{ get_hex_shade(doc.page_background or "ffffff", 5) }};
+}
+
+.table-hover tbody tr:hover td,
+.table-hover tbody tr:hover th {
+ background-color: #{{ get_hex_shade(doc.page_background or "ffffff", 10) }};
+}
+
+.table-bordered {
+ border: 1px solid #{{ get_hex_shade(doc.page_background or "ffffff", 15) }};
+}
+
+.table th,
+.table td {
+ border-top: 1px solid #{{ get_hex_shade(doc.page_background or "ffffff", 15) }};
+}
+
+.table-bordered th,
+.table-bordered td {
+ border-left: 1px solid #{{ get_hex_shade(doc.page_background or "ffffff", 15) }};
+}
+
+
+
+.hero-unit {
+ background-color: #{{ get_hex_shade(doc.page_background or "ffffff", 15) }};
+}
+
+pre, code {
+ background-color: #{{ get_hex_shade(doc.page_background or "ffffff", 5) }};
+}
+
+hr {
+ border-top: 1px solid #{{ get_hex_shade(doc.page_background or "ffffff", 15) }};
+ border-bottom: 1px solid #{{ get_hex_shade(doc.page_background or "ffffff", 5) }};
+}
diff --git a/website/doctype/style_settings/style_settings.js b/website/doctype/style_settings/style_settings.js
index 54091a3..54c4f08 100644
--- a/website/doctype/style_settings/style_settings.js
+++ b/website/doctype/style_settings/style_settings.js
@@ -17,6 +17,9 @@
cur_frm.cscript.onload_post_render = function() {
wn.require('lib/public/js/lib/jscolor/jscolor.js');
- cur_frm.fields_dict.background_color.input.className = 'color';
+ $.each(["background_color", "page_background", "page_text", "page_links",
+ "top_bar_background", "top_bar_foreground", "page_headings"], function(i, v) {
+ cur_frm.fields_dict[v].input.className = 'color';
+ })
jscolor.bind();
}
\ No newline at end of file
diff --git a/website/doctype/style_settings/style_settings.py b/website/doctype/style_settings/style_settings.py
index 5179948..1cc3467 100644
--- a/website/doctype/style_settings/style_settings.py
+++ b/website/doctype/style_settings/style_settings.py
@@ -15,6 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
+import webnotes
+
+from webnotes.utils import cint, cstr
+from webnotes import _
+
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
@@ -22,26 +27,70 @@
def validate(self):
"""make custom css"""
from jinja2 import Template
+ from website.utils import get_hex_shade
import os
+ self.validate_colors()
+
with open(os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'custom_template.css'), 'r') as f:
temp = Template(f.read())
- if not self.doc.font_size:
- self.doc.font_size = '13px'
-
- self.doc.small_font_size = str(int(self.doc.font_size[:-2])-2) + 'px'
+ self.prepare()
- self.doc.custom_css = temp.render(doc = self.doc)
+ self.doc.custom_css = temp.render(doc = self.doc, get_hex_shade=get_hex_shade)
if self.doc.add_css:
self.doc.custom_css += '\n\n/* User CSS */\n\n' + self.doc.add_css
from webnotes.sessions import clear_cache
clear_cache('Guest')
+
+ from website.utils import clear_cache
+ clear_cache()
- del self.doc.fields['small_font_size']
+ for f in ["small_font_size", "at_import", "heading_text_style"]:
+ if f in self.doc.fields:
+ del self.doc.fields[f]
+
+ def validate_colors(self):
+ if (self.doc.page_background or self.doc.page_text) and \
+ self.doc.page_background==self.doc.page_text:
+ webnotes.msgprint(_("Page text and background is same color. Please change."),
+ raise_exception=1)
+
+ if (self.doc.top_bar_background or self.doc.top_bar_foreground) and \
+ self.doc.top_bar_background==self.doc.top_bar_foreground:
+ webnotes.msgprint(_("Top Bar text and background is same color. Please change."),
+ raise_exception=1)
+
+
+ def prepare(self):
+ if not self.doc.font_size:
+ self.doc.font_size = '13px'
+
+ self.doc.small_font_size = cstr(cint(self.doc.font_size[:-2])-2) + 'px'
+ self.doc.page_border = cint(self.doc.page_border)
+
+ fonts = []
+ if self.doc.google_web_font_for_heading:
+ fonts.append(self.doc.google_web_font_for_heading)
+ if self.doc.google_web_font_for_text:
+ fonts.append(self.doc.google_web_font_for_text)
+
+ fonts = list(set(fonts))
+
+ if self.doc.heading_text_as:
+ self.doc.heading_text_style = {
+ "UPPERCASE": "uppercase",
+ "Title Case":"capitalize",
+ "lowercase": "lowercase"
+ }[self.doc.heading_text_as]
+
+ self.doc.at_import = ""
+ for f in fonts:
+ self.doc.at_import += "\n@import url(http://fonts.googleapis.com/css?family=%s:400,700);" % f.replace(" ", "+")
+
def on_update(self):
"""rebuild pages"""
diff --git a/website/doctype/style_settings/style_settings.txt b/website/doctype/style_settings/style_settings.txt
index 5f53441..df266a5 100644
--- a/website/doctype/style_settings/style_settings.txt
+++ b/website/doctype/style_settings/style_settings.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:32",
+ "creation": "2013-03-08 11:36:53",
"docstatus": 0,
- "modified": "2013-01-22 14:57:25",
+ "modified": "2013-03-14 11:57:20",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -24,24 +24,27 @@
"permlevel": 0
},
{
- "create": 1,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Style Settings",
"parentfield": "permissions",
"parenttype": "DocType",
- "permlevel": 0,
"read": 1,
- "report": 1,
+ "report": 0,
"role": "Website Manager",
- "submit": 0,
- "write": 1
+ "submit": 0
},
{
"doctype": "DocType",
"name": "Style Settings"
},
{
+ "doctype": "DocField",
+ "fieldname": "color",
+ "fieldtype": "Section Break",
+ "label": "Color"
+ },
+ {
"description": "If image is selected, color will be ignored (attach first)",
"doctype": "DocField",
"fieldname": "background_image",
@@ -58,31 +61,107 @@
},
{
"doctype": "DocField",
+ "fieldname": "page_background",
+ "fieldtype": "Data",
+ "label": "Page Background"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "page_border",
+ "fieldtype": "Check",
+ "label": "Page Border"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "page_headings",
+ "fieldtype": "Data",
+ "label": "Page Headings"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "page_text",
+ "fieldtype": "Data",
+ "label": "Page Text"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "page_links",
+ "fieldtype": "Data",
+ "label": "Page Links"
+ },
+ {
+ "doctype": "DocField",
"fieldname": "cb0",
"fieldtype": "Column Break",
+ "label": "Top Bar",
"print_width": "50%",
"width": "50%"
},
{
"doctype": "DocField",
+ "fieldname": "top_bar_background",
+ "fieldtype": "Data",
+ "label": "Top Bar Background"
+ },
+ {
+ "description": "000 is black, fff is white",
+ "doctype": "DocField",
+ "fieldname": "top_bar_foreground",
+ "fieldtype": "Data",
+ "label": "Top Bar Text"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "fonts",
+ "fieldtype": "Section Break",
+ "label": "Fonts"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "heading_font",
+ "fieldtype": "Select",
+ "label": "Font (Heading)",
+ "options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans"
+ },
+ {
+ "doctype": "DocField",
"fieldname": "font",
"fieldtype": "Select",
- "label": "Font",
+ "label": "Font (Text)",
"options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma"
},
{
"doctype": "DocField",
"fieldname": "font_size",
"fieldtype": "Select",
- "label": "Font Size",
+ "label": "Font Size (Text)",
"options": "\n12px\n13px\n14px\n15px\n16px"
},
{
"doctype": "DocField",
- "fieldname": "heading_font",
+ "fieldname": "heading_text_as",
"fieldtype": "Select",
- "label": "Heading Font",
- "options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans"
+ "label": "Heading Text As",
+ "options": "\nUPPERCASE\nTitle Case\nlowercase"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "column_break_13",
+ "fieldtype": "Column Break"
+ },
+ {
+ "description": "Add the name of <a href=\"http://google.com/webfonts\" target=\"_blank\">Google Web Font</a> e.g. \"Open Sans\"",
+ "doctype": "DocField",
+ "fieldname": "google_web_font_for_heading",
+ "fieldtype": "Data",
+ "label": "Google Web Font (Heading)"
+ },
+ {
+ "description": "Add the name of <a href=\"http://google.com/webfonts\" target=\"_blank\">Google Web Font</a> e.g. \"Open Sans\"",
+ "doctype": "DocField",
+ "fieldname": "google_web_font_for_text",
+ "fieldtype": "Data",
+ "label": "Google Web Font (Text)"
},
{
"doctype": "DocField",
@@ -115,6 +194,16 @@
"print_hide": 1
},
{
- "doctype": "DocPerm"
+ "create": 1,
+ "doctype": "DocPerm",
+ "permlevel": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 1
}
]
\ No newline at end of file
diff --git a/website/doctype/top_bar_item/top_bar_item.txt b/website/doctype/top_bar_item/top_bar_item.txt
index bc78928..0076f7f 100644
--- a/website/doctype/top_bar_item/top_bar_item.txt
+++ b/website/doctype/top_bar_item/top_bar_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2012-04-02 16:02:43",
+ "creation": "2013-02-22 01:28:08",
"docstatus": 0,
- "modified": "2012-05-07 15:21:00",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -10,10 +10,7 @@
"doctype": "DocType",
"istable": 1,
"module": "Website",
- "name": "__common__",
- "section_style": "Simple",
- "show_in_menu": 0,
- "version": 1
+ "name": "__common__"
},
{
"doctype": "DocField",
@@ -32,6 +29,7 @@
"fieldname": "label",
"fieldtype": "Data",
"label": "Label",
+ "print_width": "120px",
"width": "120px"
},
{
@@ -39,6 +37,7 @@
"fieldname": "url",
"fieldtype": "Data",
"label": "URL",
+ "print_width": "200px",
"width": "200px"
},
{
diff --git a/website/doctype/web_page/web_page.txt b/website/doctype/web_page/web_page.txt
index 861ac86..eed7d2b 100644
--- a/website/doctype/web_page/web_page.txt
+++ b/website/doctype/web_page/web_page.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-27 16:31:21",
+ "creation": "2013-02-12 13:19:11",
"docstatus": 0,
- "modified": "2013-02-12 09:33:47",
+ "modified": "2013-03-11 17:41:11",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -24,18 +24,16 @@
"permlevel": 0
},
{
- "create": 1,
+ "amend": 0,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Web Page",
"parentfield": "permissions",
"parenttype": "DocType",
- "permlevel": 0,
"read": 1,
"report": 1,
"role": "Website Manager",
- "submit": 0,
- "write": 1
+ "submit": 0
},
{
"doctype": "DocType",
@@ -86,6 +84,13 @@
"options": "Website Slideshow"
},
{
+ "description": "Description for page header.",
+ "doctype": "DocField",
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description"
+ },
+ {
"description": "Content in markdown format that appears on the main side of your page",
"doctype": "DocField",
"fieldname": "main_section",
@@ -143,6 +148,17 @@
"print_hide": 1
},
{
- "doctype": "DocPerm"
+ "cancel": 1,
+ "create": 1,
+ "doctype": "DocPerm",
+ "permlevel": 0,
+ "write": 1
+ },
+ {
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 1,
+ "write": 0
}
]
\ No newline at end of file
diff --git a/website/doctype/website_item_group/website_item_group.txt b/website/doctype/website_item_group/website_item_group.txt
index 31c4c1f..0b64306 100644
--- a/website/doctype/website_item_group/website_item_group.txt
+++ b/website/doctype/website_item_group/website_item_group.txt
@@ -1,34 +1,34 @@
[
{
- "owner": "Administrator",
+ "creation": "2013-02-22 01:28:09",
"docstatus": 0,
- "creation": "2012-12-25 13:52:11",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
- "modified": "2012-12-25 13:52:11"
+ "owner": "Administrator"
},
{
- "istable": 1,
"description": "Cross Listing of Item in multiple groups",
"doctype": "DocType",
- "module": "Website",
"document_type": "Other",
+ "istable": 1,
+ "module": "Website",
"name": "__common__"
},
{
- "parent": "Website Item Group",
"doctype": "DocField",
- "name": "__common__",
- "label": "Item Group",
- "parenttype": "DocType",
- "options": "Item Group",
"fieldname": "item_group",
"fieldtype": "Link",
- "permlevel": 0,
- "parentfield": "fields"
+ "label": "Item Group",
+ "name": "__common__",
+ "options": "Item Group",
+ "parent": "Website Item Group",
+ "parentfield": "fields",
+ "parenttype": "DocType",
+ "permlevel": 0
},
{
- "name": "Website Item Group",
- "doctype": "DocType"
+ "doctype": "DocType",
+ "name": "Website Item Group"
},
{
"doctype": "DocField"
diff --git a/website/doctype/website_product_category/website_product_category.txt b/website/doctype/website_product_category/website_product_category.txt
index 6625b47..d0b3db8 100644
--- a/website/doctype/website_product_category/website_product_category.txt
+++ b/website/doctype/website_product_category/website_product_category.txt
@@ -1,43 +1,43 @@
[
{
- "owner": "Administrator",
+ "creation": "2013-02-22 01:28:09",
"docstatus": 0,
- "creation": "2012-12-20 14:21:35",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
- "modified": "2012-12-20 15:00:25"
+ "owner": "Administrator"
},
{
- "istable": 1,
"description": "Product Category for website",
"doctype": "DocType",
- "module": "Website",
"document_type": "Transaction",
+ "istable": 1,
+ "module": "Website",
"name": "__common__"
},
{
+ "doctype": "DocField",
"name": "__common__",
"parent": "Website Product Category",
- "doctype": "DocField",
+ "parentfield": "fields",
"parenttype": "DocType",
- "permlevel": 0,
- "parentfield": "fields"
+ "permlevel": 0
},
{
- "name": "Website Product Category",
- "doctype": "DocType"
+ "doctype": "DocType",
+ "name": "Website Product Category"
},
{
"doctype": "DocField",
- "label": "Item Group",
"fieldname": "item_group",
"fieldtype": "Link",
+ "label": "Item Group",
"options": "Item Group"
},
{
"doctype": "DocField",
- "label": "Indent",
"fieldname": "indent",
"fieldtype": "Select",
+ "label": "Indent",
"options": "0\n1\n2\n3\n4\n5"
}
]
\ No newline at end of file
diff --git a/website/doctype/website_settings/website_settings.js b/website/doctype/website_settings/website_settings.js
index cbed609..67e4941 100644
--- a/website/doctype/website_settings/website_settings.js
+++ b/website/doctype/website_settings/website_settings.js
@@ -41,4 +41,14 @@
this.fieldobj.refresh_options(get_parent_options('top_bar_items'));
});
}
-});
\ No newline at end of file
+});
+
+cur_frm.cscript.set_banner_from_image = function(doc) {
+ if(!doc.banner_image) {
+ msgprint(wn._("Select a Banner Image first."));
+ }
+ var src = doc.banner_image;
+ if(src.indexOf("/")==-1) src = "files/" + src;
+ cur_frm.set_value("banner_html", "<a href='/'><img src='"+ src
+ +"' style='max-width: 200px;'></a>");
+}
\ No newline at end of file
diff --git a/website/doctype/website_settings/website_settings.py b/website/doctype/website_settings/website_settings.py
index 88af634..714b75a 100644
--- a/website/doctype/website_settings/website_settings.py
+++ b/website/doctype/website_settings/website_settings.py
@@ -31,9 +31,6 @@
from website.utils import clear_cache
clear_cache()
- from webnotes.sessions import clear_cache
- clear_cache('Guest')
-
def set_home_page(self):
import webnotes
diff --git a/website/doctype/website_settings/website_settings.txt b/website/doctype/website_settings/website_settings.txt
index 6af0575..a39144c 100644
--- a/website/doctype/website_settings/website_settings.txt
+++ b/website/doctype/website_settings/website_settings.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-25 11:35:10",
+ "creation": "2013-03-07 11:55:11",
"docstatus": 0,
- "modified": "2013-02-21 10:05:09",
+ "modified": "2013-03-13 16:25:22",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -72,24 +72,45 @@
"label": "Home Page is Products"
},
{
+ "description": "Add a banner to the site. (small banners are usually good)",
+ "doctype": "DocField",
+ "fieldname": "banner",
+ "fieldtype": "Section Break",
+ "label": "Banner"
+ },
+ {
+ "description": "Select an image of approx width 150px with a transparent background for best results.",
+ "doctype": "DocField",
+ "fieldname": "banner_image",
+ "fieldtype": "Select",
+ "label": "Banner Image",
+ "options": "attach_files:"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "set_banner_from_image",
+ "fieldtype": "Button",
+ "label": "Set Banner from Image"
+ },
+ {
+ "description": "Banner is above the Top Menu Bar.",
+ "doctype": "DocField",
+ "fieldname": "banner_html",
+ "fieldtype": "Small Text",
+ "label": "Banner HTML"
+ },
+ {
+ "description": "Menu items in the Top Bar. For setting the color of the Top Bar, go to <a href=\"#Form/Style Settings\">Style Settings</a>",
"doctype": "DocField",
"fieldname": "top_bar",
"fieldtype": "Section Break",
"label": "Top Bar"
},
{
- "description": "Background shade of the top menu bar",
- "doctype": "DocField",
- "fieldname": "top_bar_background",
- "fieldtype": "Select",
- "label": "Top Bar Background",
- "options": "Black\nWhite"
- },
- {
"description": "Brand is what appears on the top-right of the toolbar. If it is an image, make sure it\nhas a transparent background and use the <img /> tag. Keep size as 200px x 30px",
"doctype": "DocField",
"fieldname": "brand_html",
- "fieldtype": "Text",
+ "fieldtype": "Small Text",
"label": "Brand HTML"
},
{
diff --git a/website/doctype/website_slideshow_item/website_slideshow_item.txt b/website/doctype/website_slideshow_item/website_slideshow_item.txt
index d74005e..aa98745 100644
--- a/website/doctype/website_slideshow_item/website_slideshow_item.txt
+++ b/website/doctype/website_slideshow_item/website_slideshow_item.txt
@@ -1,59 +1,61 @@
[
{
- "owner": "Administrator",
+ "creation": "2013-02-22 01:28:09",
"docstatus": 0,
- "creation": "2012-12-25 16:48:49",
+ "modified": "2013-03-07 07:03:34",
"modified_by": "Administrator",
- "modified": "2012-12-25 16:55:40"
+ "owner": "Administrator"
},
{
- "istable": 1,
"allow_attach": 0,
"doctype": "DocType",
- "module": "Website",
+ "istable": 1,
"max_attachments": 10,
+ "module": "Website",
"name": "__common__"
},
{
+ "doctype": "DocField",
"name": "__common__",
"parent": "Website Slideshow Item",
- "doctype": "DocField",
+ "parentfield": "fields",
"parenttype": "DocType",
- "permlevel": 0,
- "parentfield": "fields"
+ "permlevel": 0
},
{
- "name": "Website Slideshow Item",
- "doctype": "DocType"
+ "doctype": "DocType",
+ "name": "Website Slideshow Item"
},
{
"doctype": "DocField",
- "label": "Image",
"fieldname": "image",
"fieldtype": "Select",
+ "label": "Image",
"options": "attach_files:"
},
{
"doctype": "DocField",
- "label": "Heading",
- "width": "200px",
"fieldname": "heading",
- "fieldtype": "Data"
+ "fieldtype": "Data",
+ "label": "Heading",
+ "print_width": "200px",
+ "width": "200px"
},
{
"doctype": "DocField",
- "label": "Description",
- "width": "200px",
"fieldname": "description",
- "fieldtype": "Text"
+ "fieldtype": "Text",
+ "label": "Description",
+ "print_width": "200px",
+ "width": "200px"
},
{
- "print_hide": 1,
- "no_copy": 1,
"doctype": "DocField",
- "label": "File List",
"fieldname": "file_list",
"fieldtype": "Text",
- "hidden": 1
+ "hidden": 1,
+ "label": "File List",
+ "no_copy": 1,
+ "print_hide": 1
}
]
\ No newline at end of file
diff --git a/website/helpers/blog.py b/website/helpers/blog.py
index 2bff6e5..1f25ac0 100644
--- a/website/helpers/blog.py
+++ b/website/helpers/blog.py
@@ -4,41 +4,51 @@
from __future__ import unicode_literals
import webnotes
import website.utils
+from webnotes import _
+
+def clear_blog_cache():
+ for blog in webnotes.conn.sql_list("""select page_name from
+ `tabBlog Post` where ifnull(published,0)=1"""):
+ website.utils.delete_page_cache(blog)
+
+ website.utils.delete_page_cache("writers")
@webnotes.whitelist(allow_guest=True)
-def get_blog_list(args=None):
- """
- args = {
- 'start': 0,
- }
- """
+def get_blog_list(start=0, by=None, category=None):
import webnotes
-
- if not args: args = webnotes.form_dict
-
+ condition = ""
+ if by:
+ condition = " and t1.blogger='%s'" % by.replace("'", "\'")
+ if category:
+ condition += " and t1.blog_category='%s'" % category.replace("'", "\'")
query = """\
select
- name, page_name, content, owner, creation as creation,
- title, (select count(name) from `tabComment` where
- comment_doctype='Blog' and comment_docname=`tabBlog`.name) as comments
- from `tabBlog`
- where ifnull(published,0)=1
- order by creation desc, name asc
- limit %s, 5""" % args.start
+ t1.title, t1.name, t1.page_name, t1.published_on as creation,
+ ifnull(t1.blog_intro, t1.content) as content,
+ t2.full_name, t2.avatar, t1.blogger,
+ (select count(name) from `tabComment` where
+ comment_doctype='Blog Post' and comment_docname=t1.name) as comments
+ from `tabBlog Post` t1, `tabBlogger` t2
+ where ifnull(t1.published,0)=1
+ and t1.blogger = t2.name
+ %(condition)s
+ order by published_on desc, name asc
+ limit %(start)s, 20""" % {"start": start, "condition": condition}
- result = webnotes.conn.sql(query, args, as_dict=1)
+ result = webnotes.conn.sql(query, as_dict=1)
# strip html tags from content
import webnotes.utils
for res in result:
from webnotes.utils import global_date_format, get_fullname
- res['full_name'] = get_fullname(res['owner'])
res['published'] = global_date_format(res['creation'])
if not res['content']:
res['content'] = website.utils.get_html(res['page_name'])
- res['content'] = split_blog_content(res['content'])
-
+ res['content'] = res['content'][:140]
+ if res.avatar and not "/" in res.avatar:
+ res.avatar = "files/" + res.avatar
+
return result
@webnotes.whitelist(allow_guest=True)
@@ -73,10 +83,10 @@
# notify commentors
commentors = [d[0] for d in webnotes.conn.sql("""select comment_by from tabComment where
- comment_doctype='Blog' and comment_docname=%s and
+ comment_doctype='Blog Post' and comment_docname=%s and
ifnull(unsubscribed, 0)=0""", args.get('comment_docname'))]
- blog = webnotes.conn.sql("""select * from tabBlog where name=%s""",
+ blog = webnotes.conn.sql("""select * from `tabBlog Post` where name=%s""",
args.get('comment_docname'), as_dict=1)[0]
from webnotes.utils.email_lib.bulk import send
@@ -89,10 +99,8 @@
return comment_html
@webnotes.whitelist(allow_guest=True)
-def add_subscriber():
+def add_subscriber(name, email_id):
"""add blog subscriber to lead"""
- full_name = webnotes.form_dict.get('your_name')
- email = webnotes.form_dict.get('your_email_address')
name = webnotes.conn.sql("""select name from tabLead where email_id=%s""", email)
from webnotes.model.doc import Document
@@ -104,21 +112,38 @@
if not lead.source: lead.source = 'Blog'
lead.unsubscribed = 0
lead.blog_subscriber = 1
- lead.lead_name = full_name
+ lead.lead_name = name
lead.email_id = email
lead.save()
-
+
def get_blog_content(blog_page_name):
import website.utils
content = website.utils.get_html(blog_page_name)
- content = split_blog_content(content)
import webnotes.utils
content = webnotes.utils.escape_html(content)
return content
+
+def get_blog_template_args():
+ args = {
+ "categories": webnotes.conn.sql_list("select name from `tabBlog Category` order by name")
+ }
+ args.update(webnotes.doc("Blog Settings", "Blog Settings").fields)
+ return args
-def split_blog_content(content):
- content = content.split("<!-- begin blog content -->")
- content = len(content) > 1 and content[1] or content[0]
- content = content.split("<!-- end blog content -->")
- content = content[0]
- return content
\ No newline at end of file
+def get_writers_args():
+ bloggers = webnotes.conn.sql("""select * from `tabBlogger`
+ order by posts desc""", as_dict=1)
+ for blogger in bloggers:
+ if blogger.avatar and not "/" in blogger.avatar:
+ blogger.avatar = "files/" + blogger.avatar
+
+ args = {
+ "bloggers": bloggers,
+ "texts": {
+ "all_posts_by": _("All posts by")
+ },
+ "categories": webnotes.conn.sql_list("select name from `tabBlog Category` order by name")
+ }
+
+ args.update(webnotes.doc("Blog Settings", "Blog Settings").fields)
+ return args
\ No newline at end of file
diff --git a/website/helpers/blog_feed.py b/website/helpers/blog_feed.py
index 20c78ca..41c203e 100644
--- a/website/helpers/blog_feed.py
+++ b/website/helpers/blog_feed.py
@@ -44,7 +44,7 @@
<description>%(content)s</description>
<link>%(link)s</link>
<guid>%(name)s</guid>
- <pubDate>%(creation)s</pubDate>
+ <pubDate>%(published_on)s</pubDate>
</item>"""
def generate():
@@ -57,13 +57,12 @@
items = ''
blog_list = webnotes.conn.sql("""\
- select page_name as name, modified, creation, title from tabBlog
+ select page_name as name, published_on, modified, title, content from `tabBlog Post`
where ifnull(published,0)=1
- order by creation desc, modified desc, name asc limit 100""", as_dict=1)
+ order by published_on desc limit 20""", as_dict=1)
for blog in blog_list:
blog.link = host + '/' + blog.name + '.html'
- blog.content = get_blog_content(blog.name)
items += rss_item % blog
diff --git a/website/page/website_home/website_home.js b/website/page/website_home/website_home.js
index c6b2253..e112207 100644
--- a/website/page/website_home/website_home.js
+++ b/website/page/website_home/website_home.js
@@ -12,11 +12,6 @@
doctype:"Web Page"
},
{
- label: wn._("Blog"),
- description: wn._("Blog entry."),
- doctype:"Blog"
- },
- {
label: wn._("Website Slideshow"),
description: wn._("Embed image slideshows in website pages."),
doctype:"Website Slideshow"
@@ -24,6 +19,34 @@
]
},
{
+ title: wn._("Blog"),
+ icon: "icon-edit",
+ items: [
+ {
+ label: wn._("Blog Post"),
+ description: wn._("Single Post (article)."),
+ doctype:"Blog Post"
+ },
+ {
+ label: wn._("Blogger"),
+ description: wn._("Profile of a blog writer."),
+ doctype:"Blogger"
+ },
+ {
+ label: wn._("Blog Category"),
+ description: wn._("Categorize blog posts."),
+ doctype:"Blog Category"
+ },
+ {
+ label: wn._("Blog Settings"),
+ description: wn._("Write titles and introductions to your blog."),
+ doctype:"Blog Settings",
+ route: "Form/Blog Settings"
+ },
+ ]
+ },
+
+ {
title: wn._("Website Overall Settings"),
icon: "icon-wrench",
right: true,
@@ -45,6 +68,7 @@
{
title: wn._("Special Page Settings"),
icon: "icon-wrench",
+ right: true,
items: [
{
"route":"Form/Product Settings",
diff --git a/website/templates/css/login.css b/website/templates/css/login.css
index 710f889..c2a7af2 100644
--- a/website/templates/css/login.css
+++ b/website/templates/css/login.css
@@ -6,6 +6,7 @@
.layout-wrapper {
background-color: #fff;
+ color: #333;
padding: 10px;
box-shadow: 1px 1px 3px 3px #ccc;
font-size: 12px;
diff --git a/website/templates/css/product_page.css b/website/templates/css/product_page.css
index 5780ee4..566b6b5 100644
--- a/website/templates/css/product_page.css
+++ b/website/templates/css/product_page.css
@@ -1,6 +1,6 @@
<style>
.item-main-image {
- max-width: 400px;
+ max-width: 100%;
margin: auto;
}
.web-long-description {
diff --git a/website/templates/html/base.html b/website/templates/html/base.html
index fa01f8a..2719f8d 100644
--- a/website/templates/html/base.html
+++ b/website/templates/html/base.html
@@ -19,6 +19,9 @@
<link rel="icon" href="app/images/favicon.ico" type="image/x-icon">
{% endif %}
+ {% if description %}
+ <meta name="description" content="{{ description }}">
+ {% endif %}
{% block header %}
{% endblock %}
diff --git a/website/templates/html/blog_footer.html b/website/templates/html/blog_footer.html
new file mode 100644
index 0000000..e439d14
--- /dev/null
+++ b/website/templates/html/blog_footer.html
@@ -0,0 +1,13 @@
+<div class="span12">
+ <hr />
+ {% if categories %}
+ <h5>Explore posts by categories</h5>
+ <ul class="breadcrumb" style="background-color: transparent; padding-left: 0px;">
+ {% for category in categories %}
+ <li><a href="blog?category={{ category }}">{{ category }}</a>
+ {% if not loop.last %}<span class="divider">/</span>{% endif %}</li>
+ {% endfor %}
+ <br><br>
+ {% endif %}
+ <p>Show posts by <a href="blog">everyone</a>. Meet the <a href="writers">writers</a> of this blog</p>
+</div>
diff --git a/website/templates/html/blog_page.html b/website/templates/html/blog_page.html
index 24dd8d7..270d427 100644
--- a/website/templates/html/blog_page.html
+++ b/website/templates/html/blog_page.html
@@ -9,45 +9,48 @@
{% endblock %}
{% block content %}
-<div class="span12">
- <h2>{{ title }}</h2>
+<div class="span12" itemscope itemtype="http://schema.org/BlogPost">
+ <h2 itemprop="name headline">{{ title }}</h2>
<!-- begin blog content -->
- <div class="help">By {{ full_name }} on {{ updated }}</div>
+ <div class="help" style="color: #aaa">
+ <span itemprop="author">{{ blogger_info and blogger_info.full_name or full_name }}</span> /
+ <span itemprop="dateCreated">{{ updated }}</span></div>
<br>
+ <div itemprop="articleBody">
{{ content_html }}
+ </div>
<!-- end blog content -->
-
+ {% if blogger_info %}
+ <hr />
+ {% include "html/blogger.html" %}
+ {% endif %}
<hr>
- <h3>Comments</h3><br>
+ <h3>{{ texts.comments }}</h3><br>
<div class="blog-comments">
{% if not comment_list %}
- <div class="alert no-comment">
- <p>Be the first one to comment</p>
+ <div class="no-comment">
+ <p>{{ texts.first_comment }}</p>
</div>
{% endif %}
{% include 'html/comment.html' %}
</div>
- <div><button class="btn add-comment">Add Comment</button></div>
+ <div><button class="btn add-comment">{{ texts.add_comment }}</button></div>
<div style="display: none; margin-top: 10px;"
- id="comment-form" class="well">
+ id="comment-form">
<div class="alert" style="display:none;"></div>
<form>
- <p>
- <input name="comment_by_fullname" placeholder="Your Name" />
- </p>
- <p>
- <input name="comment_by" placeholder="Your Email Id" />
- </p>
- <p>
+ <fieldset>
+ <input name="comment_by_fullname" placeholder="Your Name" type="text"/><br>
+ <input name="comment_by" placeholder="Your Email Id" type="text"/><br>
<textarea name="comment" placeholder="Comment" style="width: 300px; height: 120px;"/>
- </textarea>
- </p>
- <p>
- <button class="btn btn-info" id="submit-comment">Submit</button>
+ </textarea><br>
+ <button class="btn btn-info" id="submit-comment">{{ texts.submit }}</button>
+ </fieldset>
</form>
</div>
</div>
+{% include 'html/blog_footer.html' %}
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/html/blogger.html b/website/templates/html/blogger.html
new file mode 100644
index 0000000..e18f86a
--- /dev/null
+++ b/website/templates/html/blogger.html
@@ -0,0 +1,13 @@
+<div class="row">
+ <div class="span2">
+ <div class="avatar avatar-large">
+ <img itemprop="thumbnailUrl" src="{{ blogger_info.avatar }}" />
+ </div>
+ </div>
+ <div class="span10">
+ <h4>{{ blogger_info.full_name }}</h4>
+ <p style="color: #999">{{ blogger_info.bio }}</p>
+ <p><a href="blog?by={{ blogger_info.name }}&by_name={{ blogger_info.full_name }}">
+ {{ texts.all_posts_by }} {{ blogger_info.full_name }}</a></p>
+ </div>
+</div>
\ No newline at end of file
diff --git a/website/templates/html/comment.html b/website/templates/html/comment.html
index 1323e09..27baaad 100644
--- a/website/templates/html/comment.html
+++ b/website/templates/html/comment.html
@@ -3,12 +3,15 @@
it is to be included in the blog/blog.html template
#}
-{% for comment in comment_list %}
-<div class="comment-row">
- <div class="comment-title">
- {{ comment.comment_by_fullname }} - {{ comment.comment_date }}:
+<div itemscope itemtype="http://schema.org/UserComments">
+ {% for comment in comment_list %}
+ <div class="comment-row">
+ <div class="comment-title">
+ <span itemprop="name" class="author">{{ comment.comment_by_fullname }}</span> /
+ <span itemprop="commentTime">{{ comment.comment_date }}</span>:
+ </div>
+ <p class="comment-content" itemprop="commentText">{{ comment.comment }}</p>
+ <hr>
</div>
- <p class="comment-content">{{ comment.comment }}</p>
- <hr>
-</div>
-{% endfor %}
\ No newline at end of file
+ {% endfor %}
+</div>
\ No newline at end of file
diff --git a/website/templates/html/footer.html b/website/templates/html/footer.html
new file mode 100644
index 0000000..2f1c7fe
--- /dev/null
+++ b/website/templates/html/footer.html
@@ -0,0 +1,71 @@
+<footer class="container"><div class="web-footer">
+ {% if facebook_share or google_plus_one or twitter_share or linked_in_share %}
+ <div class="social-icons" style="">
+ <span style="font-size: 11px;">{{ share_text or "Share this page on: "}}</span>
+ {% if google_plus_one %}
+ <a href="https://plus.google.com/share?url={{ url }}"
+ target="_blank"><i class="icon-google-plus"></i></a>
+ {% endif %}
+ {% if twitter_share %}
+ <a href="https://twitter.com/intent/tweet?url={{ url }}&text={{ encoded_title }}"
+ target="_blank" ><i class="icon-twitter"></i></a>
+ {% endif %}
+ {% if facebook_share %}
+ <a href="https://www.facebook.com/sharer.php?u={{ url }}&t={{ encoded_title }}&via={{ twitter_share_via }}"
+ target="_blank"><i class="icon-facebook"></i></a>
+ {% endif %}
+ {% if linked_in_share %}
+ <a href="http://www.linkedin.com/shareArticle?mini=true&url={{ url }}&title={{ encoded_title }}"
+ target="_blank"><i class="icon-linkedin"></i></a>
+ {% endif %}
+ </div>
+ {% endif %}
+ <p style="float: right; clear: right;">
+ <a style="font-size: 90%; color: #888;" href="attributions">ERPNext Powered</a>
+ </p>
+ <div class="web-footer-menu">
+ <ul>
+ {% for item in footer_items %}
+ <li><a href="{{ item.url }}" {{ item.target }}
+ data-label="{{ item.label }}">{{ item.label }}</a></li>
+ {% endfor %}
+ </ul>
+ </div>
+ {% if copyright %}
+ <div class="web-footer-copyright">© {{ copyright }}</div>
+ {% endif %}
+ {% if address %}
+ {{ address }}
+ {% endif %}
+ <p><div class="input-append" style="text-align: center; margin:30px 0px;">
+ <input class="span3" id="footer-subscribe-email" type="text" placeholder="Your email address...">
+ <button class="btn" type="button" id="footer-subscribe-button">Stay Updated</button>
+ </div></p>
+ <script>
+ $("#footer-subscribe-button").click(function() {
+
+ $("#footer-subscribe-email").attr('disabled', true);
+ $("#footer-subscribe-button").html("Sending...")
+ .attr("disabled", true);
+
+ if($("#footer-subscribe-email").val()) {
+ erpnext.send_message({
+ subject:"Subscribe me",
+ sender: $("#footer-subscribe-email").val(),
+ message: "Subscribe to newsletter (via website footer).",
+ callback: function(r) {
+ if(!r.exc) {
+ $("#footer-subscribe-button").html("Thank You :)")
+ .addClass("btn-success").attr("disabled", true);
+ } else {
+ $("#footer-subscribe-button").html("Error :( Not a valid id?")
+ .addClass("btn-danger").attr("disabled", false);
+ $("#footer-subscribe-email").val("").attr('disabled', false);
+ }
+ }
+ });
+ }
+ });
+ </script>
+ </div>
+</footer>
diff --git a/website/templates/html/navbar.html b/website/templates/html/navbar.html
new file mode 100644
index 0000000..8112499
--- /dev/null
+++ b/website/templates/html/navbar.html
@@ -0,0 +1,57 @@
+<div class="navbar navbar-inverse"
+ style="">
+ <div class="navbar-inner">
+ {% if brand_html %}<a class="brand" href="index">{{ brand_html }}</a>{% endif %}
+ <div class="container">
+ <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <div class="nav-collapse collapse">
+ <ul class="nav">
+ {% for page in top_bar_items %}
+ {% if not page.parent_label %}
+ <li data-label="{{ page.label }}"
+ {% if page.child_items %}
+ class="dropdown"
+ {% endif %}>
+ <a href="{{ page.url or '#' }}"
+ {% if page.child_items %}
+ class="dropdown-toggle"
+ onclick="return false;"
+ data-toggle="dropdown"
+ {% endif %}
+ {{ page.target or ''}}>
+ {{ page.label }}
+ {% if page.child_items %}
+ <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ {% for child in page.child_items %}
+ <li data-label="{{ child.label }}">
+ <a {% if child.indent %}
+ style="padding-left:
+ {{(int(child.indent)+1)*15 }}px"
+ {% endif %}
+ href="{{ child.url }}" {{ child.target or '' }}>
+ {{ child.label }}
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+ {% else %}
+ </a>
+ {% endif %}
+ </li>
+ {% endif %}
+ {% endfor %}
+ </ul>
+ <ul class="nav pull-right">
+ <li id="login-topbar-item"><a href="login">Login</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+</div>
+<script>$('.dropdown-toggle').dropdown()</script>
diff --git a/website/templates/html/outer.html b/website/templates/html/outer.html
index a8b73ad..f7296e4 100644
--- a/website/templates/html/outer.html
+++ b/website/templates/html/outer.html
@@ -1,114 +1,20 @@
-{#
- requires, brand_html, top_bar_items, footer_items, copyright, content, address
-#}
-
{% extends "html/base.html" %}
{% block body %}
<header>
</header>
<div class="container">
+ {% if banner_html %}<div class="row" style="margin-top: 30px;">
+ <div class="span12">{{ banner_html }}</div>
+ </div>{% endif %}
<div class="outer">
- <div class="navbar{% if top_bar_background=="Black" %} navbar-inverse{% endif %}"
- style="margin-bottom: 0px;">
- <div class="navbar-inner">
- <a class="brand" href="index">{{ brand_html }}</a>
- <div class="container">
- <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <div class="nav-collapse collapse">
- <ul class="nav">
- {% for page in top_bar_items %}
- {% if not page.parent_label %}
- <li data-label="{{ page.label }}"
- {% if page.child_items %}
- class="dropdown"
- {% endif %}>
- <a href="{{ page.url or '#' }}"
- {% if page.child_items %}
- class="dropdown-toggle"
- onclick="return false;"
- data-toggle="dropdown"
- {% endif %}
- {{ page.target or ''}}>
- {{ page.label }}
- {% if page.child_items %}
- <b class="caret"></b>
- </a>
- <ul class="dropdown-menu">
- {% for child in page.child_items %}
- <li data-label="{{ child.label }}">
- <a {% if child.indent %}
- style="padding-left:
- {{(int(child.indent)+1)*15 }}px"
- {% endif %}
- href="{{ child.url }}" {{ child.target or '' }}>
- {{ child.label }}
- </a>
- </li>
- {% endfor %}
- </ul>
- {% else %}
- </a>
- {% endif %}
- </li>
- {% endif %}
- {% endfor %}
- </ul>
- <ul class="nav pull-right">
- <li id="login-topbar-item"><a href="login">Login</a></li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <script>$('.dropdown-toggle').dropdown()</script>
+ {% include "html/navbar.html" %}
<div class="content row" id="page-{{ name }}" style="display: block;">
{% block content %}
{% endblock %}
</div>
</div>
</div>
- <footer class="container"><div class="web-footer">
- {% if facebook_share or google_plus_one or twitter_share or linked_in_share %}
- <div class="social-icons" style="">
- <span style="font-size: 11px;">{{ share_text or "Share this page on: "}}</span>
- {% if google_plus_one %}
- <a href="https://plus.google.com/share?url={{ url }}"
- target="_blank"><i class="icon-google-plus"></i></a>
- {% endif %}
- {% if twitter_share %}
- <a href="https://twitter.com/intent/tweet?url={{ url }}&text={{ encoded_title }}"
- target="_blank" ><i class="icon-twitter"></i></a>
- {% endif %}
- {% if facebook_share %}
- <a href="https://www.facebook.com/sharer.php?u={{ url }}&t={{ encoded_title }}&via={{ twitter_share_via }}"
- target="_blank"><i class="icon-facebook"></i></a>
- {% endif %}
- {% if linked_in_share %}
- <a href="http://www.linkedin.com/shareArticle?mini=true&url={{ url }}&title={{ encoded_title }}"
- target="_blank"><i class="icon-linkedin"></i></a>
- {% endif %}
- </div>
- {% endif %}
- <p style="float: right; clear: right;">
- <a style="font-size: 90%; color: #888;" href="attributions">ERPNext Powered</a></p>
- <div class="web-footer-menu"><ul>
- {% for item in footer_items %}
- <li><a href="{{ item.url }}" {{ item.target }}
- data-label="{{ item.label }}">{{ item.label }}</a></li>
- {% endfor %}
- </ul></div>
- {% if copyright %}
- <div class="web-footer-copyright">© {{ copyright }}</div>
- {% endif %}
- {% if address %}
- {{ address }}
- {% endif %}
- </div>
- </footer>
+ {% include "html/footer.html" %}
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/html/product_in_list.html b/website/templates/html/product_in_list.html
index 43b0134..97de596 100644
--- a/website/templates/html/product_in_list.html
+++ b/website/templates/html/product_in_list.html
@@ -8,6 +8,5 @@
</div>
<div style="height: 100px; overflow: hidden; font-size: 80%;">
<h4 style="margin-bottom: 2px;"><a href="{{ page_name }}">{{ item_name }}</a></h4>
- <p class="help">Item Code: {{ name }}</p>
</div>
</div>
\ No newline at end of file
diff --git a/website/templates/html/product_page.html b/website/templates/html/product_page.html
index eaf4ca8..f897a31 100644
--- a/website/templates/html/product_page.html
+++ b/website/templates/html/product_page.html
@@ -11,46 +11,42 @@
{% block content %}
{% include 'html/product_search_box.html' %}
{% include 'html/product_breadcrumbs.html' %}
- <div class="span12">
- <h3 itemprop="name">{{ item_name }}</h3>
- <p class="help">Item Code: {{ name }}</p>
- </div>
<div class="span12 product-page-content" itemscope itemtype="http://schema.org/Product">
- {% if slideshow %}
- {% include "html/slideshow.html" %}
- {% else %}
- {% if website_image %}
- <image itemprop="image" class="item-main-image"
- src="{{ website_image }}" />
- {% else %}
- <div class="img-area">
- {% include 'html/product_missing_image.html' %}
- </div>
- {% endif %}
- {% endif %}
- <br><br>
<div class="row">
- <div class="span9">
- <h3>Product Description</h3>
+ <div class="span6">
+ {% if slideshow %}
+ {% include "html/slideshow.html" %}
+ {% else %}
+ {% if website_image %}
+ <image itemprop="image" class="item-main-image"
+ src="{{ website_image }}" />
+ {% else %}
+ <div class="img-area">
+ {% include 'html/product_missing_image.html' %}
+ </div>
+ {% endif %}
+ {% endif %}
+ </div>
+ <div class="span6">
+ <h3 itemprop="name" style="margin-top: 0px;">{{ item_name }}</h3>
+ <p class="help">Item Code: {{ name }}</p>
+ <h4>Product Description</h4>
<div itemprop="description">
{{ web_long_description or web_short_description or
"[No description given]" }}
</div>
- <hr>
{% if obj.doclist.get({"doctype":"Item Website Specification"}) %}
- <h3>Specifications</h3>
- <table class="table table-striped table-bordered" style="width: 100%">
- {% for d in obj.doclist.get(
- {"doctype":"Item Website Specification"}) %}
- <tr>
- <td style="width: 30%;">{{ d.label }}</td>
- <td>{{ d.description }}</td>
- </tr>
- {% endfor %}
- </table>
+ <h4>Specifications</h4>
+ <table class="table table-bordered" style="width: 100%">
+ {% for d in obj.doclist.get(
+ {"doctype":"Item Website Specification"}) %}
+ <tr>
+ <td style="width: 30%;">{{ d.label }}</td>
+ <td>{{ d.description }}</td>
+ </tr>
+ {% endfor %}
+ </table>
{% endif %}
- </div>
- <div class="span3">
<div class="item-price hide">
<p>Price:</p>
</div>
diff --git a/website/templates/html/slideshow.html b/website/templates/html/slideshow.html
index 8641724..e0e9038 100644
--- a/website/templates/html/slideshow.html
+++ b/website/templates/html/slideshow.html
@@ -5,10 +5,12 @@
{% for slide in obj.slides %}
<div class="{% if slide.idx==1 %}active {% endif %}item">
<img src="{{ slide.image }}" />
+ {% if slide.heading or slide.description %}
<div class="carousel-caption">
- <h4>{{ slide.heading }}</h4>
- <p>{{ slide.description }}</p>
+ {% if slide.heading %}<h4>{{ slide.heading }}</h4>{% endif %}
+ {% if slide.heading %}<p>{{ slide.description }}</p>{% endif %}
</div>
+ {% endif %}
</div>
{% endfor %}
</div>
diff --git a/website/templates/js/blog.js b/website/templates/js/blog.js
index 6c006de..fd5a156 100644
--- a/website/templates/js/blog.js
+++ b/website/templates/js/blog.js
@@ -23,6 +23,15 @@
$("#next-page").click(function() {
blog.get_list();
})
+
+ if(get_url_arg("by_name")) {
+ $("#blot-subtitle").html("Posts by " + get_url_arg("by_name")).toggle(true);
+ }
+
+ if(get_url_arg("category")) {
+ $("#blot-subtitle").html("Posts filed under " + get_url_arg("category")).toggle(true);
+ }
+
});
var blog = {
@@ -33,10 +42,14 @@
url: "server.py",
data: {
cmd: "website.helpers.blog.get_blog_list",
- start: blog.start
+ start: blog.start,
+ by: get_url_arg("by"),
+ category: get_url_arg("category")
},
dataType: "json",
success: function(data) {
+ $(".progress").toggle(false);
+ if(data.exc) console.log(data.exc);
blog.render(data.message);
}
});
@@ -51,19 +64,30 @@
b.comment_text = '1 comment.'
} else {
b.comment_text = b.comments + ' comments.'
- }
+ }
- $(repl('<h2><a href="%(page_name)s">%(title)s</a></h2>\
- <div class="help">%(comment_text)s</div>\
- %(content)s<br />\
- <p><a href="%(page_name)s">Read with comments...</a></p>\
- <hr /><br />', b)).appendTo($wrap);
+ b.page_name = encodeURIComponent(b.page_name);
+
+ $(repl('<div class="row">\
+ <div class="span1">\
+ <div class="avatar avatar-medium" style="margin-top: 6px;">\
+ <img src="%(avatar)s" />\
+ </div>\
+ </div>\
+ <div class="span11">\
+ <h4><a href="%(page_name)s">%(title)s</a></h4>\
+ <p>%(content)s</p>\
+ <p style="color: #aaa; font-size: 90%">\
+ <a href="blog?by=%(blogger)s&by_name=%(full_name)s">\
+ %(full_name)s</a> wrote this on %(published)s / %(comment_text)s</p>\
+ </div>\
+ </div><hr>', b)).appendTo($wrap);
});
blog.start += (data.length || 0);
- if(!data.length) {
+ if(!data.length || data.length < 20) {
if(blog.start) {
$("#next-page").toggle(false)
- .parent().append("<div class='alert'>Nothing more to show.</div>");
+ .parent().append("<div class='alert alert-info'>Nothing more to show.</div>");
} else {
$("#next-page").toggle(false)
.parent().append("<div class='alert'>No blogs written yet.</div>");
diff --git a/website/templates/js/blog_page.js b/website/templates/js/blog_page.js
index d5e9970..efdd6bc 100644
--- a/website/templates/js/blog_page.js
+++ b/website/templates/js/blog_page.js
@@ -36,7 +36,7 @@
comment_by: $("[name='comment_by']").val(),
comment: $("[name='comment']").val(),
cmd: "website.helpers.blog.add_comment",
- comment_doctype: "Blog",
+ comment_doctype: "Blog Post",
comment_docname: "{{ name }}",
page_name: "{{ page_name }}",
_type: "POST"
diff --git a/website/templates/pages/about.html b/website/templates/pages/about.html
index 30d9a5d..380c543 100644
--- a/website/templates/pages/about.html
+++ b/website/templates/pages/about.html
@@ -7,34 +7,27 @@
{{ obj.doc.company_introduction or "<h2>About Us</h2><p>Some Introduction about your company that you would like your website visitor to know. More people than you think will read your About page. People always like to know who the are doing business with. Be authentic and avoid using jargon like 'value added services' etc. Be sure to update your company history and list of key team members in Website > About Us Settings</p>" }}
{% if obj.doclist.get({"doctype":"Company History"}) %}
<h3>{{ obj.doc.company_history_heading or "Company History" }}</h3>
- <table class="table table-bordered" style="width: 100%; table-layout: fixed">
- <tbody>
- {% for d in obj.doclist.get({"doctype":"Company History"}) %}
- <tr>
- <td style="width: 30%; text-align: right"><h4>{{ d.year }}</h4></td>
- <td>{{ d.highlight }}</td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
+ {% for d in obj.doclist.get({"doctype":"Company History"}) %}
+ <div class="row">
+ <span class="span2"><h4 style="margin:0px;">{{ d.year }}</h4></span>
+ <span class="span10"><p>{{ d.highlight }}</p></span>
+ </div>
+ {% endfor %}
{% endif %}
- {% if obj.doclist.get({"doctype":"Employee"}) %}
+ {% if obj.doclist.get({"doctype":"About Us Team Member"}) %}
<h3>{{ obj.doc.team_members_heading or "Team Members" }}</h3>
- <table class="table" style="width: 100%; table-layout: fixed">
- <tbody>
- {% for d in obj.doclist.get({"doctype":"Employee"}) %}
- <tr itemscope itemtype="http://schema.org/Person">
- <td style="text-align:right; width: 20%;">
- <div class="avatar avatar-x-large">
- <img class="avatar" src="{{ d.image }}" style="" itemprop="image">
- </div>
- </td>
- <td><h4 itemprop="name">{{ d.employee_name }}</h4>
- <div itemprop="description">{{ d.bio }}</div></td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
+ {% for d in obj.doclist.get({"doctype":"About Us Team Member"}) %}
+ <div class="row" itemscope itemtype="http://schema.org/Person">
+ <span class="span2">
+ <div class="avatar avatar-large">
+ <img class="avatar" src="{{ d.image_link }}" style="" itemprop="image">
+ </div>
+ </span>
+ <span class="span10"><h4 itemprop="name">{{ d.full_name }}</h4>
+ <p itemprop="description">{{ d.bio }}</p>
+ </span>
+ </div>
+ {% endfor %}
{% endif %}
{{ obj.doc.footer or "" }}
</div>
diff --git a/website/templates/pages/attributions.html b/website/templates/pages/attributions.html
index 2d195ba..9e4b50d 100644
--- a/website/templates/pages/attributions.html
+++ b/website/templates/pages/attributions.html
@@ -12,7 +12,7 @@
{% block content %}
<div class="layout-attributions span12">
- <h3>This website is made using these Awesome Open Source Projects <i class="icon-heart" style="color: red"></i></h3>
+ <h3>This website is made using these awesome Open Source projects <i class="icon-heart" style="color: red"></i></h3>
<hr>
<table class="table table-bordered table-striped">
<tbody>
@@ -38,6 +38,10 @@
<td>The Number One HTTP Server On The Internet.</td>
</tr>
<tr>
+ <td><a href="http://memcached.org/">Memcached</a></td>
+ <td>Free & open source, high-performance, distributed memory object caching system.</td>
+ </tr>
+ <tr>
<td><a href="http://python.org/">Python Programming Language</a></td>
<td>The "batteries included" language that lets you write elegant code, quickly.<br><br>Python Libraries:
<ul>
@@ -81,6 +85,10 @@
<td>A lightning fast JavaScript grid/spreadsheet.</td>
</tr>
<tr>
+ <td><a href="http://arshaw.com/fullcalendar/">FullCalendar</a></td>
+ <td>FullCalendar is a jQuery plugin that provides a full-sized, drag and drop calendar.</td>
+ </tr>
+ <tr>
<td><a href="http://www.flotcharts.org/">Flot Charting Library</a></td>
<td>Attractive JavaScript plotting for jQuery.</td>
</tr>
@@ -97,12 +105,36 @@
<td>HTML/Javascript Color Picker.</td>
</tr>
<tr>
+ <td><a href="http://qunitjs.com/">QUnit</a></td>
+ <td>A JavaScript Unit Testing framework.</td>
+ </tr>
+ <tr>
<td><a href="https://github.com/dcneiner/Downloadify">Downloadify - Flash Download Widget</a></td>
<td>A tiny javascript + Flash library that enables the creation and download of text files without server interaction.</td>
</tr>
</tbody>
</table>
+
+ <hr>
+ <h3>ERPNext License: GNU/General Public License</h3>
+ <div class="well">
+ <p><b>ERPNext - Open Source, web based ERP</b></p>
+ <p>Copyright © 2012, Web Notes Technologies Pvt Ltd, India</p>
- <p class="alert">Note: A link to this page must be easily accessible.</p>
+ <p>This program is free software: you can redistribute it and/or modify
+ it under the terms of the <b>GNU General Public License</b> as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.</p>
+
+ <p>This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.</p>
+
+ <p>For complete license see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a></p>
+ </div>
+ <p class="alert">Note: A link to this page must be easily accessible and all other ERPNext branding must remain as it is.</p>
+ <hr>
+ <p>For more information please write to us at support@erpnext.com</p>
</div>
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/blog.html b/website/templates/pages/blog.html
index 3c2a579..df258e1 100644
--- a/website/templates/pages/blog.html
+++ b/website/templates/pages/blog.html
@@ -12,8 +12,15 @@
{% block content %}
<div class="span12">
- <h1>Blog</h1>
+ <h2 id="blog-title">{{ blog_title }}</h2>
+ {% if blog_introduction %}
+ <p>{{ blog_introduction }}</p>
+ {% endif %}
+ <h3 id="blot-subtitle" style="display:none;"></h3>
<br>
+ <div class="progress progress-striped active">
+ <div class="bar" style="width: 100%;"></div>
+ </div>
<div id="blog-list">
<!-- blog list will be generated dynamically -->
</div>
@@ -22,4 +29,5 @@
style="display:none;">More...</button>
</div>
</div>
+{% include 'html/blog_footer.html' %}
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/writers.html b/website/templates/pages/writers.html
new file mode 100644
index 0000000..bba3749
--- /dev/null
+++ b/website/templates/pages/writers.html
@@ -0,0 +1,17 @@
+{% extends "html/page.html" %}
+
+{% set title="Blog Writers" %}
+
+{% block content %}
+<div class="span12">
+ <h2 id="blog-title">Blog Writers</h2>
+ {% if writers_introduction %}
+ <p>{{ writers_introduction }}</p>
+ {% endif %}
+ <hr>
+ {% for blogger_info in bloggers %}
+ {% include "html/blogger.html" %}
+ {% endfor %}
+</div>
+{% include 'html/blog_footer.html' %}
+{% endblock %}
\ No newline at end of file
diff --git a/website/utils.py b/website/utils.py
index 97c03bc..443bde0 100644
--- a/website/utils.py
+++ b/website/utils.py
@@ -25,7 +25,7 @@
"template": 'html/web_page.html',
"condition_field": "published"
}),
- 'Blog': webnotes._dict({
+ 'Blog Post': webnotes._dict({
"template": 'html/blog_page.html',
"condition_field": "published",
}),
@@ -40,10 +40,14 @@
}
page_settings_map = {
- "about": "About Us Settings",
- "contact": "Contact Us Settings"
+ "about": "website.doctype.about_us_settings.about_us_settings.get_args",
+ "contact": "Contact Us Settings",
+ "blog": "website.helpers.blog.get_blog_template_args",
+ "writers": "website.helpers.blog.get_writers_args"
}
+no_cache = "message"
+
def render(page_name):
"""render html page"""
try:
@@ -66,10 +70,12 @@
# load from cache, if auto cache clear is falsy
if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0):
- html = webnotes.cache().get_value("page:" + page_name)
- from_cache = True
+ if not page_name in no_cache:
+ html = webnotes.cache().get_value("page:" + page_name)
+ from_cache = True
if not html:
+ webnotes.connect()
html = load_into_cache(page_name)
from_cache = False
@@ -155,7 +161,11 @@
'name': page_name,
})
if page_name in page_settings_map:
- args.obj = webnotes.bean(page_settings_map[page_name]).obj
+ target = page_settings_map[page_name]
+ if "." in target:
+ args.update(webnotes.get_method(target)())
+ else:
+ args.obj = webnotes.bean(page_settings_map[page_name]).obj
else:
args = get_doc_fields(page_name)
@@ -249,18 +259,13 @@
args.update(ret)
settings = webnotes.doc("Website Settings", "Website Settings")
- for k in ["brand_html", "copyright", "address", "top_bar_background", "favicon",
- "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "twitter_share_via"]:
+ for k in ["banner_html", "brand_html", "copyright", "address", "twitter_share_via"
+ "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]:
if k in settings.fields:
args[k] = settings.fields.get(k)
for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]:
args[k] = int(args.get(k) or 0)
-
- if not args.brand_html:
- args.brand_html = "ERPNext"
- if not args.top_bar_background:
- args.top_bar_background = "Black"
args.url = quote(str(get_request_site_address(full_address=True)), str(""))
args.encoded_title = quote(str(args.title or ""), str(""))
@@ -301,4 +306,32 @@
if url and not url.lower().startswith("http"):
return "files/" + url
else:
- return url
\ No newline at end of file
+ return url
+
+def get_hex_shade(color, percent):
+
+ def p(c):
+ v = int(c, 16) + int(int('ff', 16) * (float(percent)/100))
+ if v < 0:
+ v=0
+ if v > 255:
+ v=255
+ h = hex(v)[2:]
+ if len(h) < 2:
+ h = "0" + h
+ return h
+
+ r, g, b = color[0:2], color[2:4], color[4:6]
+
+ avg = (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3)
+ # switch dark and light shades
+ if avg > 128:
+ percent = -percent
+
+ # stronger diff for darker shades
+ if percent < 25 and avg < 64:
+ percent = percent * 2
+
+ return p(r) + p(g) + p(b)
+
+
\ No newline at end of file