mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-20 21:49:18 +00:00
[merge conflict]
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
13
accounts/README.md
Normal file
13
accounts/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Accounts module contains masters and transactions to manage a traditional
|
||||
double entry accounting system.
|
||||
|
||||
Accounting heads are called "Accounts" and they can be groups in a tree like
|
||||
"Chart of Accounts"
|
||||
|
||||
Entries are:
|
||||
|
||||
- Journal Vouchers
|
||||
- Sales Invoice (Itemised)
|
||||
- Purchase Invoice (Itemised)
|
||||
|
||||
All accounting entries are stored in the `General Ledger`
|
||||
11
accounts/doctype/account/README.md
Normal file
11
accounts/doctype/account/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
Account DocType represents an Accounting Ledger or Group.
|
||||
|
||||
Follows a composite model. `parent_account` represents the parent of an Account except
|
||||
a root account.
|
||||
There can be only 4 root accounts: Income, Expense, Assets and Liabilities in a company.
|
||||
|
||||
Other features:
|
||||
|
||||
- It can be of type Debit or Credit.
|
||||
- A Group is a collection of groups or ledgers
|
||||
|
||||
@@ -29,6 +29,7 @@ class DocType:
|
||||
self.nsm_parent_field = 'parent_account'
|
||||
|
||||
def autoname(self):
|
||||
"""Append abbreviation to company on naming"""
|
||||
self.doc.name = self.doc.account_name.strip() + ' - ' + \
|
||||
webnotes.conn.get_value("Company", self.doc.company, "abbr")
|
||||
|
||||
@@ -37,6 +38,7 @@ class DocType:
|
||||
return {'address': address}
|
||||
|
||||
def validate_master_name(self):
|
||||
"""Remind to add master name"""
|
||||
if (self.doc.master_type == 'Customer' or self.doc.master_type == 'Supplier') \
|
||||
and not self.doc.master_name:
|
||||
msgprint("Message: Please enter Master Name once the account is created.")
|
||||
@@ -62,6 +64,7 @@ class DocType:
|
||||
self.doc.debit_or_credit = par[0][3]
|
||||
|
||||
def validate_max_root_accounts(self):
|
||||
"""Raise exception if there are more than 4 root accounts"""
|
||||
if webnotes.conn.sql("""select count(*) from tabAccount where
|
||||
company=%s and ifnull(parent_account,'')='' and docstatus != 2""",
|
||||
self.doc.company)[0][0] > 4:
|
||||
@@ -69,7 +72,6 @@ class DocType:
|
||||
raise_exception=1)
|
||||
|
||||
def validate_duplicate_account(self):
|
||||
|
||||
if self.doc.fields.get('__islocal') or not self.doc.name:
|
||||
company_abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
|
||||
if sql("""select name from tabAccount where name=%s""",
|
||||
@@ -134,6 +136,7 @@ class DocType:
|
||||
self.doc.parent_account = ''
|
||||
|
||||
def update_nsm_model(self):
|
||||
"""update lft, rgt indices for nested set model"""
|
||||
import webnotes
|
||||
import webnotes.utils.nestedset
|
||||
webnotes.utils.nestedset.update_nsm(self)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-05-09 13:16:11",
|
||||
"creation": "2013-05-24 12:15:51",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-23 12:52:09",
|
||||
"modified": "2013-05-30 12:09:39",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -18,8 +18,7 @@
|
||||
"parent": "POS Setting",
|
||||
"parentfield": "fields",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
@@ -44,7 +43,8 @@
|
||||
"label": "User",
|
||||
"oldfieldname": "user",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Profile"
|
||||
"options": "Profile",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -54,6 +54,7 @@
|
||||
"oldfieldname": "territory",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Territory",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -64,6 +65,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "naming_series",
|
||||
"oldfieldtype": "Select",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -74,6 +76,7 @@
|
||||
"oldfieldname": "currency",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Currency",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -84,6 +87,7 @@
|
||||
"label": "Conversion Rate",
|
||||
"oldfieldname": "conversion_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -94,6 +98,7 @@
|
||||
"oldfieldname": "price_list_name",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "link:Price List",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -105,13 +110,24 @@
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break"
|
||||
"oldfieldtype": "Column Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "Create Stock Ledger Entries when you submit a Sales Invoice",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "update_stock",
|
||||
"fieldtype": "Check",
|
||||
"label": "Update Stock",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -121,6 +137,7 @@
|
||||
"oldfieldname": "customer_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
@@ -131,6 +148,7 @@
|
||||
"oldfieldname": "cash_bank_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -141,6 +159,7 @@
|
||||
"oldfieldname": "income_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -152,6 +171,7 @@
|
||||
"label": "Expense Account",
|
||||
"options": "Account",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
@@ -162,6 +182,7 @@
|
||||
"oldfieldname": "warehouse",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -172,6 +193,7 @@
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -181,7 +203,8 @@
|
||||
"label": "Charge",
|
||||
"oldfieldname": "charge",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Sales Taxes and Charges Master"
|
||||
"options": "Sales Taxes and Charges Master",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -191,7 +214,8 @@
|
||||
"oldfieldname": "letter_head",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "link:Letter Head",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -200,7 +224,8 @@
|
||||
"label": "Terms and Conditions",
|
||||
"oldfieldname": "tc_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Terms and Conditions"
|
||||
"options": "Terms and Conditions",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -210,17 +235,10 @@
|
||||
"label": "Select Print Heading",
|
||||
"oldfieldname": "select_print_heading",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "link:Print Heading"
|
||||
"options": "link:Print Heading",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "System Manager",
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Accounts Manager",
|
||||
|
||||
@@ -17,86 +17,56 @@
|
||||
cur_frm.cscript.tname = "Purchase Invoice Item";
|
||||
cur_frm.cscript.fname = "entries";
|
||||
cur_frm.cscript.other_fname = "purchase_tax_details";
|
||||
|
||||
wn.provide("erpnext.accounts");
|
||||
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
|
||||
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
|
||||
|
||||
erpnext.buying.PurchaseInvoiceController = erpnext.buying.BuyingController.extend({
|
||||
erpnext.accounts.PurchaseInvoiceController = erpnext.buying.BuyingController.extend({
|
||||
onload: function() {
|
||||
this._super();
|
||||
|
||||
if(!this.frm.doc.__islocal) {
|
||||
// show credit_to in print format
|
||||
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
|
||||
this.frm.set_df_property("credit_to", "print_hide", 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
refresh: function(doc) {
|
||||
this._super();
|
||||
|
||||
// Show / Hide button
|
||||
if(doc.docstatus==1 && doc.outstanding_amount > 0)
|
||||
cur_frm.add_custom_button('Make Payment Entry', cur_frm.cscript.make_bank_voucher);
|
||||
this.frm.add_custom_button('Make Payment Entry', this.make_bank_voucher);
|
||||
|
||||
if(doc.docstatus==1) {
|
||||
cur_frm.add_custom_button('View Ledger', cur_frm.cscript.view_ledger_entry);
|
||||
this.frm.add_custom_button('View Ledger', this.view_ledger_entry);
|
||||
}
|
||||
|
||||
cur_frm.cscript.is_opening(doc);
|
||||
this.is_opening(doc);
|
||||
},
|
||||
onload_post_render: function(doc, dt, dn) {
|
||||
var me = this;
|
||||
var callback1 = function(doc, dt, dn) {
|
||||
var callback2 = function(doc, dt, dn) {
|
||||
if(doc.__islocal && doc.supplier) cur_frm.cscript.supplier(doc, dt, dn);
|
||||
}
|
||||
me.update_item_details(doc, dt, dn, callback2);
|
||||
}
|
||||
|
||||
// TODO: improve this
|
||||
if(this.frm.doc.__islocal) {
|
||||
if (this.frm.fields_dict.price_list_name && this.frm.doc.price_list_name) {
|
||||
this.price_list_name(callback1);
|
||||
} else {
|
||||
callback1(doc, dt, dn);
|
||||
}
|
||||
}
|
||||
|
||||
credit_to: function() {
|
||||
this.supplier();
|
||||
},
|
||||
|
||||
write_off_amount: function() {
|
||||
this.calculate_outstanding_amount();
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
allocated_amount: function() {
|
||||
this.calculate_total_advance("Purchase Invoice", "advance_allocation_details");
|
||||
this.frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
|
||||
var new_cscript = new erpnext.buying.PurchaseInvoiceController({frm: cur_frm});
|
||||
|
||||
// for backward compatibility: combine new and previous states
|
||||
$.extend(cur_frm.cscript, new_cscript);
|
||||
$.extend(cur_frm.cscript, new erpnext.accounts.PurchaseInvoiceController({frm: cur_frm}));
|
||||
|
||||
|
||||
cur_frm.cscript.onload = function(doc,dt,dn) {
|
||||
if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()});
|
||||
}
|
||||
|
||||
cur_frm.cscript.supplier = function(doc,dt,dn) {
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
get_server_fields('get_credit_to','','',doc, dt, dn, 0, callback2);
|
||||
}
|
||||
|
||||
var callback2 = function(r,rt){
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
var el = getchildren('Purchase Invoice Item',doc.name,'entries');
|
||||
for(var i in el){
|
||||
if(el[i].item_code && (!el[i].expense_head || !el[i].cost_center)){
|
||||
args = {
|
||||
item_code: el[i].item_code,
|
||||
expense_head: el[i].expense_head,
|
||||
cost_center: el[i].cost_center
|
||||
};
|
||||
get_server_fields('get_default_values', JSON.stringify(args), 'entries', doc, el[i].doctype, el[i].name, 1);
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.calc_amount(doc, 1);
|
||||
}
|
||||
|
||||
if (doc.supplier) {
|
||||
get_server_fields('get_default_supplier_address',
|
||||
JSON.stringify({ supplier: doc.supplier }),'', doc, dt, dn, 1, function(doc, dt, dn) {
|
||||
cur_frm.refresh();
|
||||
callback(doc, dt, dn);
|
||||
});
|
||||
unhide_field(['supplier_address','contact_person']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cur_frm.cscript.supplier_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.supplier) get_server_fields('get_supplier_address', JSON.stringify({supplier: doc.supplier, address: doc.supplier_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
@@ -112,23 +82,6 @@ cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.credit_to = function(doc,dt,dn) {
|
||||
|
||||
var callback = function(doc, dt, dn) {
|
||||
var doc = locals[doc.doctype][doc.name];
|
||||
if(doc.supplier) {
|
||||
get_server_fields('get_default_supplier_address',
|
||||
JSON.stringify({ supplier: doc.supplier }), '', doc, dt, dn, 1, function() {
|
||||
cur_frm.refresh();
|
||||
});
|
||||
unhide_field(['supplier_address','contact_person']);
|
||||
}
|
||||
cur_frm.refresh();
|
||||
}
|
||||
|
||||
get_server_fields('get_cust', '', '', doc, dt, dn, 1, callback);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['entries'].grid.onrowadd = function(doc, cdt, cdn){
|
||||
|
||||
cl = getchildren('Purchase Invoice Item', doc.name, cur_frm.cscript.fname, doc.doctype);
|
||||
@@ -152,17 +105,6 @@ cur_frm.cscript.is_opening = function(doc, dt, dn) {
|
||||
if (doc.is_opening == 'Yes') unhide_field('aging_date');
|
||||
}
|
||||
|
||||
cur_frm.cscript.write_off_amount = function(doc) {
|
||||
doc.total_amount_to_pay = flt(doc.grand_total) - flt(doc.write_off_amount);
|
||||
doc.outstanding_amount = flt(doc.total_amount_to_pay) - flt(doc.total_advance);
|
||||
refresh_many(['outstanding_amount', 'total_amount_to_pay']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.recalculate = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.calculate_tax(doc,cdt,cdn);
|
||||
calc_total_advance(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||
var callback = function(r,rt) {
|
||||
unhide_field(['supplier_address', 'contact_person']);
|
||||
@@ -171,11 +113,6 @@ cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||
$c_obj(make_doclist(dt,dn),'pull_details','',callback);
|
||||
}
|
||||
|
||||
cur_frm.cscript.allocated_amount = function(doc,cdt,cdn) {
|
||||
calc_total_advance(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.make_bank_voucher = function() {
|
||||
wn.call({
|
||||
method: "accounts.doctype.journal_voucher.journal_voucher.get_default_bank_cash_account",
|
||||
@@ -261,21 +198,6 @@ cur_frm.cscript.cost_center = function(doc, cdt, cdn){
|
||||
refresh_field('entries');
|
||||
}
|
||||
|
||||
calc_total_advance = function(doc,cdt,cdn) {
|
||||
var doc = locals[doc.doctype][doc.name];
|
||||
var el = getchildren('Purchase Invoice Advance',doc.name,'advance_allocation_details')
|
||||
var total_advance = 0;
|
||||
for(var i in el) {
|
||||
if (! el[i].allocated_amount == 0) {
|
||||
total_advance += flt(el[i].allocated_amount);
|
||||
}
|
||||
}
|
||||
doc.total_amount_to_pay = flt(doc.grand_total) - flt(doc.write_off_amount);
|
||||
doc.total_advance = flt(total_advance);
|
||||
doc.outstanding_amount = flt(doc.total_amount_to_pay) - flt(total_advance);
|
||||
refresh_many(['total_advance','outstanding_amount', 'total_amount_to_pay']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_jv = function(doc, dt, dn, bank_account) {
|
||||
var jv = wn.model.make_new_doc_and_get_name('Journal Voucher');
|
||||
jv = locals['Journal Voucher'][jv];
|
||||
|
||||
@@ -91,6 +91,11 @@ class DocType(BuyingController):
|
||||
msgprint("%s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company))
|
||||
return ret
|
||||
|
||||
def set_supplier_defaults(self):
|
||||
self.doc.fields.update(self.get_cust())
|
||||
self.doc.fields.update(self.get_credit_to())
|
||||
super(DocType, self).set_supplier_defaults()
|
||||
|
||||
def get_cust(self):
|
||||
ret = {}
|
||||
if self.doc.credit_to:
|
||||
@@ -100,31 +105,6 @@ class DocType(BuyingController):
|
||||
|
||||
return ret
|
||||
|
||||
def get_default_values(self, args):
|
||||
if isinstance(args, basestring):
|
||||
import json
|
||||
args = json.loads(args)
|
||||
|
||||
out = webnotes._dict()
|
||||
|
||||
item = webnotes.conn.sql("""select name, purchase_account, cost_center,
|
||||
is_stock_item from `tabItem` where name=%s""", args.get("item_code"), as_dict=1)
|
||||
|
||||
if item and item[0]:
|
||||
item = item[0]
|
||||
|
||||
if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) and \
|
||||
item.is_stock_item == "Yes":
|
||||
# unset expense head for stock item and auto inventory accounting
|
||||
out.expense_head = out.cost_center = None
|
||||
else:
|
||||
if not args.get("expense_head"):
|
||||
out.expense_head = item.purchase_account
|
||||
if not args.get("cost_center"):
|
||||
out.cost_center = item.cost_center
|
||||
|
||||
return out
|
||||
|
||||
def pull_details(self):
|
||||
if self.doc.purchase_receipt_main:
|
||||
self.validate_duplicate_docname('purchase_receipt')
|
||||
@@ -466,9 +446,9 @@ class DocType(BuyingController):
|
||||
# expense will be booked in sales invoice
|
||||
stock_item_and_auto_inventory_accounting = True
|
||||
|
||||
valuation_amt = (flt(item.amount, self.precision.item.amount) +
|
||||
flt(item.item_tax_amount, self.precision.item.item_tax_amount) +
|
||||
flt(item.rm_supp_cost, self.precision.item.rm_supp_cost))
|
||||
valuation_amt = (flt(item.amount, self.precision("amount", item)) +
|
||||
flt(item.item_tax_amount, self.precision("item_tax_amount", item)) +
|
||||
flt(item.rm_supp_cost, self.precision("rm_supp_cost", item)))
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-05-07 13:50:30",
|
||||
"creation": "2013-05-21 16:16:39",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-13 11:12:56",
|
||||
"modified": "2013-05-28 12:18:35",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -89,10 +89,11 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "supplier_name",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Name",
|
||||
"oldfieldname": "supplier_name",
|
||||
@@ -100,34 +101,38 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "address_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Address",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Contact",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_mobile",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Mobile No",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_email",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Contact Email",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
@@ -392,6 +397,7 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_section",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -399,7 +405,6 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "supplier_address",
|
||||
"fieldtype": "Link",
|
||||
@@ -415,7 +420,6 @@
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.supplier",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_person",
|
||||
"fieldtype": "Link",
|
||||
|
||||
@@ -24,6 +24,7 @@ from webnotes.utils import cint
|
||||
import webnotes.defaults
|
||||
|
||||
test_dependencies = ["Item", "Cost Center"]
|
||||
test_ignore = ["Serial No"]
|
||||
|
||||
class TestPurchaseInvoice(unittest.TestCase):
|
||||
def test_gl_entries_without_auto_inventory_accounting(self):
|
||||
@@ -119,25 +120,6 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
wrapper.insert()
|
||||
wrapper.load_from_db()
|
||||
|
||||
self.assertEqual(wrapper.doclist[0].net_total, 1250)
|
||||
|
||||
# tax amounts
|
||||
expected_values = [
|
||||
["_Test Account Shipping Charges - _TC", 100, 1350],
|
||||
["_Test Account Customs Duty - _TC", 125, 1350],
|
||||
["_Test Account Excise Duty - _TC", 140, 1490],
|
||||
["_Test Account Education Cess - _TC", 2.8, 1492.8],
|
||||
["_Test Account S&H Education Cess - _TC", 1.4, 1494.2],
|
||||
["_Test Account CST - _TC", 29.88, 1524.08],
|
||||
["_Test Account VAT - _TC", 156.25, 1680.33],
|
||||
["_Test Account Discount - _TC", 168.03, 1512.30],
|
||||
]
|
||||
|
||||
for i, tax in enumerate(wrapper.doclist.get({"parentfield": "purchase_tax_details"})):
|
||||
self.assertEqual(tax.account_head, expected_values[i][0])
|
||||
self.assertEqual(tax.tax_amount, expected_values[i][1])
|
||||
self.assertEqual(tax.total, expected_values[i][2])
|
||||
|
||||
expected_values = [
|
||||
["_Test Item Home Desktop 100", 90, 59],
|
||||
["_Test Item Home Desktop 200", 135, 177]
|
||||
@@ -147,13 +129,41 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertEqual(item.item_tax_amount, expected_values[i][1])
|
||||
self.assertEqual(item.valuation_rate, expected_values[i][2])
|
||||
|
||||
self.assertEqual(wrapper.doclist[0].net_total, 1250)
|
||||
|
||||
# tax amounts
|
||||
expected_values = [
|
||||
["_Test Account Shipping Charges - _TC", 100, 1350],
|
||||
["_Test Account Customs Duty - _TC", 125, 1350],
|
||||
["_Test Account Excise Duty - _TC", 140, 1490],
|
||||
["_Test Account Education Cess - _TC", 2.8, 1492.8],
|
||||
["_Test Account S&H Education Cess - _TC", 1.4, 1494.2],
|
||||
["_Test Account CST - _TC", 29.88, 1524.08],
|
||||
["_Test Account VAT - _TC", 156.25, 1680.33],
|
||||
["_Test Account Discount - _TC", 168.03, 1512.30],
|
||||
]
|
||||
|
||||
for i, tax in enumerate(wrapper.doclist.get({"parentfield": "purchase_tax_details"})):
|
||||
self.assertEqual(tax.account_head, expected_values[i][0])
|
||||
self.assertEqual(tax.tax_amount, expected_values[i][1])
|
||||
self.assertEqual(tax.total, expected_values[i][2])
|
||||
|
||||
def test_purchase_invoice_with_subcontracted_item(self):
|
||||
wrapper = webnotes.bean(copy=test_records[0])
|
||||
wrapper.doclist[1].item_code = "_Test FG Item"
|
||||
wrapper.run_method("calculate_taxes_and_totals")
|
||||
wrapper.insert()
|
||||
wrapper.load_from_db()
|
||||
|
||||
|
||||
expected_values = [
|
||||
["_Test FG Item", 90, 7059],
|
||||
["_Test Item Home Desktop 200", 135, 177]
|
||||
]
|
||||
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])
|
||||
self.assertEqual(item.valuation_rate, expected_values[i][2])
|
||||
|
||||
self.assertEqual(wrapper.doclist[0].net_total, 1250)
|
||||
|
||||
# tax amounts
|
||||
@@ -172,15 +182,6 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertEqual(tax.account_head, expected_values[i][0])
|
||||
self.assertEqual(tax.tax_amount, expected_values[i][1])
|
||||
self.assertEqual(tax.total, expected_values[i][2])
|
||||
|
||||
expected_values = [
|
||||
["_Test FG Item", 90, 7059],
|
||||
["_Test Item Home Desktop 200", 135, 177]
|
||||
]
|
||||
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])
|
||||
self.assertEqual(item.valuation_rate, expected_values[i][2])
|
||||
|
||||
def test_purchase_invoice_with_advance(self):
|
||||
from accounts.doctype.journal_voucher.test_journal_voucher \
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-04-19 11:00:06",
|
||||
"creation": "2013-05-21 16:16:04",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-07 11:23:56",
|
||||
"modified": "2013-05-28 12:02:02",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -101,7 +101,7 @@
|
||||
"oldfieldname": "tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
@@ -159,35 +159,5 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"description": "Cheating Field\nPlease do not delete ",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "total_tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Total +Tax",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "total_tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"description": "Cheating Field\nPlease do not delete ",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Tax Amount",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "total_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"report_hide": 1
|
||||
}
|
||||
]
|
||||
@@ -22,52 +22,90 @@ cur_frm.cscript.sales_team_fname = "sales_team";
|
||||
// print heading
|
||||
cur_frm.pformat.print_heading = 'Invoice';
|
||||
|
||||
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
||||
wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
||||
|
||||
// On Load
|
||||
// -------
|
||||
cur_frm.cscript.onload = function(doc,dt,dn) {
|
||||
cur_frm.cscript.manage_rounded_total();
|
||||
if(!doc.customer && doc.debit_to) wn.meta.get_docfield(dt, 'debit_to', dn).print_hide = 0;
|
||||
if (doc.__islocal) {
|
||||
if(!doc.due_date) set_multiple(dt,dn,{due_date:get_today()});
|
||||
if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()});
|
||||
if(!doc.currency && sys_defaults.currency) set_multiple(dt,dn,{currency:sys_defaults.currency});
|
||||
if(!doc.price_list_currency) set_multiple(dt, dn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
|
||||
var callback = function(doc, dt, dn) {
|
||||
// called from mapper, update the account names for items and customer
|
||||
var callback2 = function(doc, dt, dn) {
|
||||
if(doc.customer && doc.__islocal) {
|
||||
$c_obj(make_doclist(doc.doctype,doc.name),
|
||||
'load_default_accounts','',
|
||||
function(r,rt) {
|
||||
refresh_field('entries');
|
||||
cur_frm.cscript.customer(doc,dt,dn,onload=true);
|
||||
}
|
||||
);
|
||||
wn.provide("erpnext.accounts");
|
||||
erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.extend({
|
||||
onload: function() {
|
||||
this._super();
|
||||
|
||||
if(!this.frm.doc.__islocal) {
|
||||
// show debit_to in print format
|
||||
if(!this.frm.doc.customer && this.frm.doc.debit_to) {
|
||||
this.frm.set_df_property("debit_to", "print_hide", 0);
|
||||
}
|
||||
}
|
||||
// defined in sales_common.js
|
||||
var callback1 = function(doc, dt, dn) {
|
||||
//for previously created sales invoice, set required field related to pos
|
||||
cur_frm.cscript.update_item_details(doc, dt, dn, callback2);
|
||||
},
|
||||
|
||||
refresh: function(doc, dt, dn) {
|
||||
this._super();
|
||||
|
||||
cur_frm.cscript.is_opening(doc, dt, dn);
|
||||
|
||||
if(doc.docstatus==1) {
|
||||
cur_frm.add_custom_button('View Ledger', cur_frm.cscript.view_ledger_entry);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
|
||||
if(doc.is_pos==1 && doc.update_stock!=1)
|
||||
cur_frm.add_custom_button('Make Delivery', cur_frm.cscript['Make Delivery Note']);
|
||||
|
||||
if(doc.outstanding_amount!=0)
|
||||
cur_frm.add_custom_button('Make Payment Entry', cur_frm.cscript.make_bank_voucher);
|
||||
}
|
||||
cur_frm.cscript.hide_fields(doc, dt, dn);
|
||||
},
|
||||
|
||||
is_pos: function() {
|
||||
if(cint(this.frm.doc.is_pos)) {
|
||||
if(!this.frm.doc.company) {
|
||||
this.frm.set_value("is_pos", 0);
|
||||
msgprint(wn._("Please specify Company to proceed"));
|
||||
} else {
|
||||
var me = this;
|
||||
this.frm.call({
|
||||
doc: me.frm.doc,
|
||||
method: "set_missing_values",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(doc.is_pos ==1) cur_frm.cscript.is_pos(doc, dt, dn,callback1);
|
||||
else cur_frm.cscript.update_item_details(doc, dt, dn, callback2);
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_price_list_currency(doc, dt, dn, callback);
|
||||
|
||||
}
|
||||
// TODO toggle display of fields
|
||||
},
|
||||
|
||||
debit_to: function() {
|
||||
this.customer();
|
||||
},
|
||||
|
||||
allocated_amount: function() {
|
||||
this.calculate_total_advance("Sales Invoice", "advance_adjustment_details");
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
write_off_outstanding_amount_automatically: function() {
|
||||
if(cint(this.frm.doc.write_off_outstanding_amount_automatically)) {
|
||||
wn.model.round_floats_in(this.frm.doc, ["grand_total", "paid_amount"]);
|
||||
// this will make outstanding amount 0
|
||||
this.frm.set_value("write_off_amount",
|
||||
flt(this.frm.doc.grand_total - this.frm.doc.paid_amount), precision("write_off_amount"));
|
||||
}
|
||||
|
||||
this.frm.runclientscript("write_off_amount");
|
||||
},
|
||||
|
||||
write_off_amount: function() {
|
||||
this.calculate_outstanding_amount();
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
paid_amount: function() {
|
||||
this.write_off_outstanding_amount_automatically();
|
||||
},
|
||||
});
|
||||
|
||||
// for backward compatibility: combine new and previous states
|
||||
$.extend(cur_frm.cscript, new erpnext.accounts.SalesInvoiceController({frm: cur_frm}));
|
||||
|
||||
// Hide Fields
|
||||
// ------------
|
||||
@@ -87,15 +125,12 @@ cur_frm.cscript.hide_fields = function(doc, cdt, cdn) {
|
||||
hide_field(par_flds);
|
||||
unhide_field('payments_section');
|
||||
for(f in item_flds_normal) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_normal[f], false);
|
||||
for(f in item_flds_pos) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_pos[f], (doc.update_stock==1?true:false));
|
||||
} else {
|
||||
hide_field('payments_section');
|
||||
unhide_field(par_flds);
|
||||
for(f in item_flds_normal) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_normal[f], true);
|
||||
for(f in item_flds_pos) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_pos[f], false);
|
||||
}
|
||||
|
||||
cur_frm.toggle_display("contact_section", doc.customer);
|
||||
for(f in item_flds_pos) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_pos[f], (cint(doc.update_stock)==1?true:false));
|
||||
|
||||
// India related fields
|
||||
var cp = wn.control_panel;
|
||||
@@ -104,50 +139,6 @@ cur_frm.cscript.hide_fields = function(doc, cdt, cdn) {
|
||||
}
|
||||
|
||||
|
||||
// Refresh
|
||||
// -------
|
||||
cur_frm.cscript.refresh = function(doc, dt, dn) {
|
||||
cur_frm.cscript.is_opening(doc, dt, dn);
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
// Show / Hide button
|
||||
cur_frm.clear_custom_buttons();
|
||||
if (!cur_frm.cscript.is_onload) cur_frm.cscript.hide_price_list_currency(doc, dt, dn);
|
||||
|
||||
if(doc.docstatus==1) {
|
||||
cur_frm.add_custom_button('View Ledger', cur_frm.cscript.view_ledger_entry);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
|
||||
if(doc.is_pos==1 && doc.update_stock!=1)
|
||||
cur_frm.add_custom_button('Make Delivery', cur_frm.cscript['Make Delivery Note']);
|
||||
|
||||
if(doc.outstanding_amount!=0)
|
||||
cur_frm.add_custom_button('Make Payment Entry', cur_frm.cscript.make_bank_voucher);
|
||||
}
|
||||
cur_frm.cscript.hide_fields(doc, dt, dn);
|
||||
|
||||
}
|
||||
|
||||
//fetch retail transaction related fields
|
||||
//--------------------------------------------
|
||||
cur_frm.cscript.is_pos = function(doc,dt,dn,callback){
|
||||
cur_frm.cscript.hide_fields(doc, dt, dn);
|
||||
if(doc.is_pos == 1){
|
||||
if (!doc.company) {
|
||||
msgprint("Please select company to proceed");
|
||||
doc.is_pos = 0;
|
||||
refresh_field('is_pos');
|
||||
}
|
||||
else {
|
||||
var callback1 = function(r,rt){
|
||||
if(callback) callback(doc, dt, dn);
|
||||
cur_frm.refresh();
|
||||
}
|
||||
$c_obj(make_doclist(dt,dn),'set_pos_fields','',callback1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.mode_of_payment = function(doc) {
|
||||
cur_frm.call({
|
||||
method: "get_bank_cash_account",
|
||||
@@ -159,94 +150,10 @@ cur_frm.cscript.update_stock = function(doc, dt, dn) {
|
||||
cur_frm.cscript.hide_fields(doc, dt, dn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.warehouse = function(doc, cdt , cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (!d.item_code) { msgprint("please enter item code first"); return };
|
||||
if (d.warehouse) {
|
||||
arg = "{'item_code':'" + d.item_code + "','warehouse':'" + d.warehouse +"'}";
|
||||
get_server_fields('get_actual_qty',arg,'entries',doc,cdt,cdn,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn,onload) {
|
||||
cur_frm.toggle_display("contact_section", doc.customer);
|
||||
|
||||
var pl = doc.price_list_name;
|
||||
var callback = function(r,rt) {
|
||||
var callback2 = function(doc, dt, dn) {
|
||||
doc = locals[dt][dn];
|
||||
if(doc.debit_to && doc.posting_date){
|
||||
get_server_fields('get_cust_and_due_date','','',doc,dt,dn,1,
|
||||
function(doc, dt, dn) {
|
||||
cur_frm.refresh();
|
||||
if (!onload && (pl != doc.price_list_name)) cur_frm.cscript.price_list_name(doc, dt, dn);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
get_server_fields('get_debit_to','','',doc, dt, dn, 0, callback2);
|
||||
}
|
||||
var args = onload ? 'onload':''
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', args, callback);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
// Set Due Date = posting date + credit days
|
||||
cur_frm.cscript.debit_to = function(doc,dt,dn) {
|
||||
|
||||
var callback2 = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
cur_frm.refresh();
|
||||
}
|
||||
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
if(doc.customer) $c_obj(make_doclist(dt,dn), 'get_default_customer_address', '', callback2);
|
||||
cur_frm.toggle_display("contact_section", doc.customer);
|
||||
|
||||
cur_frm.refresh();
|
||||
}
|
||||
|
||||
if(doc.debit_to && doc.posting_date){
|
||||
get_server_fields('get_cust_and_due_date','','',doc,dt,dn,1,callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//refresh advance amount
|
||||
//-------------------------------------------------
|
||||
|
||||
|
||||
cur_frm.cscript.write_off_outstanding_amount_automatically = function(doc) {
|
||||
if (doc.write_off_outstanding_amount_automatically == 1)
|
||||
doc.write_off_amount = flt(doc.grand_total) - flt(doc.paid_amount);
|
||||
|
||||
doc.outstanding_amount = flt(doc.grand_total) - flt(doc.paid_amount) - flt(doc.write_off_amount);
|
||||
refresh_field(['write_off_amount', 'outstanding_amount']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.paid_amount = function(doc) {
|
||||
cur_frm.cscript.write_off_outstanding_amount_automatically(doc);
|
||||
}
|
||||
|
||||
cur_frm.cscript.write_off_amount = function(doc) {
|
||||
cur_frm.cscript.write_off_outstanding_amount_automatically(doc);
|
||||
}
|
||||
|
||||
|
||||
//Set debit and credit to zero on adding new row
|
||||
//----------------------------------------------
|
||||
cur_frm.fields_dict['entries'].grid.onrowadd = function(doc, cdt, cdn){
|
||||
|
||||
cl = getchildren('Sales Invoice Item', doc.name, cur_frm.cscript.fname, doc.doctype);
|
||||
@@ -282,12 +189,6 @@ cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||
|
||||
|
||||
|
||||
// Allocated Amount in advances table
|
||||
// -----------------------------------
|
||||
cur_frm.cscript.allocated_amount = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.calc_adjustment_amount(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
//Make Delivery Note Button
|
||||
//-----------------------------
|
||||
|
||||
@@ -452,19 +353,6 @@ cur_frm.cscript.cost_center = function(doc, cdt, cdn){
|
||||
refresh_field(cur_frm.cscript.fname);
|
||||
}
|
||||
|
||||
cur_frm.cscript.calc_adjustment_amount = function(doc,cdt,cdn) {
|
||||
var doc = locals[doc.doctype][doc.name];
|
||||
var el = getchildren('Sales Invoice Advance',doc.name,'advance_adjustment_details');
|
||||
var total_adjustment_amt = 0
|
||||
for(var i in el) {
|
||||
total_adjustment_amt += flt(el[i].allocated_amount)
|
||||
}
|
||||
doc.total_advance = flt(total_adjustment_amt);
|
||||
doc.outstanding_amount = flt(doc.grand_total) - flt(total_adjustment_amt) - flt(doc.paid_amount) - flt(doc.write_off_amount);
|
||||
refresh_many(['total_advance','outstanding_amount']);
|
||||
}
|
||||
|
||||
|
||||
// Make Journal Voucher
|
||||
// --------------------
|
||||
cur_frm.cscript.make_jv = function(doc, dt, dn, bank_account) {
|
||||
|
||||
@@ -41,7 +41,6 @@ class DocType(SellingController):
|
||||
|
||||
def validate(self):
|
||||
super(DocType, self).validate()
|
||||
self.fetch_missing_values()
|
||||
self.validate_posting_time()
|
||||
self.so_dn_required()
|
||||
self.validate_proj_cust()
|
||||
@@ -50,7 +49,6 @@ class DocType(SellingController):
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.check_conversion_rate(self)
|
||||
sales_com_obj.validate_max_discount(self, 'entries')
|
||||
sales_com_obj.get_allocated_sum(self)
|
||||
sales_com_obj.validate_fiscal_year(self.doc.fiscal_year,
|
||||
self.doc.posting_date,'Posting Date')
|
||||
self.validate_customer()
|
||||
@@ -59,18 +57,22 @@ class DocType(SellingController):
|
||||
self.validate_fixed_asset_account()
|
||||
self.clear_unallocated_advances("Sales Invoice Advance", "advance_adjustment_details")
|
||||
self.add_remarks()
|
||||
|
||||
if cint(self.doc.is_pos):
|
||||
self.validate_pos()
|
||||
self.validate_write_off_account()
|
||||
if cint(self.doc.update_stock):
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.validate_serial_no(self, 'entries')
|
||||
sl.validate_serial_no(self, 'packing_details')
|
||||
self.validate_item_code()
|
||||
self.update_current_stock()
|
||||
self.validate_delivery_note()
|
||||
|
||||
if cint(self.doc.update_stock):
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.validate_serial_no(self, 'entries')
|
||||
sl.validate_serial_no(self, 'packing_details')
|
||||
self.validate_item_code()
|
||||
self.update_current_stock()
|
||||
self.validate_delivery_note()
|
||||
|
||||
if not self.doc.is_opening:
|
||||
self.doc.is_opening = 'No'
|
||||
|
||||
self.set_aging_date()
|
||||
self.set_against_income_account()
|
||||
self.validate_c_form()
|
||||
@@ -80,16 +82,15 @@ class DocType(SellingController):
|
||||
|
||||
|
||||
def on_submit(self):
|
||||
if cint(self.doc.is_pos) == 1:
|
||||
if cint(self.doc.update_stock) == 1:
|
||||
sl_obj = get_obj("Stock Ledger")
|
||||
sl_obj.validate_serial_no_warehouse(self, 'entries')
|
||||
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
|
||||
|
||||
sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
|
||||
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
|
||||
|
||||
self.update_stock_ledger(update_stock=1)
|
||||
if cint(self.doc.update_stock) == 1:
|
||||
sl_obj = get_obj("Stock Ledger")
|
||||
sl_obj.validate_serial_no_warehouse(self, 'entries')
|
||||
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
|
||||
|
||||
sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
|
||||
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
|
||||
|
||||
self.update_stock_ledger(update_stock=1)
|
||||
else:
|
||||
# Check for Approving Authority
|
||||
if not self.doc.recurring_id:
|
||||
@@ -114,13 +115,12 @@ class DocType(SellingController):
|
||||
self.update_time_log_batch(None)
|
||||
|
||||
def on_cancel(self):
|
||||
if cint(self.doc.is_pos) == 1:
|
||||
if cint(self.doc.update_stock) == 1:
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
|
||||
sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
|
||||
|
||||
self.update_stock_ledger(update_stock = -1)
|
||||
if cint(self.doc.update_stock) == 1:
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
|
||||
sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
|
||||
|
||||
self.update_stock_ledger(update_stock = -1)
|
||||
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.check_stop_sales_order(self)
|
||||
@@ -136,25 +136,16 @@ class DocType(SellingController):
|
||||
self.validate_recurring_invoice()
|
||||
self.convert_to_recurring()
|
||||
|
||||
def fetch_missing_values(self):
|
||||
# fetch contact and address details for customer, if they are not mentioned
|
||||
if not (self.doc.contact_person and self.doc.customer_address):
|
||||
for fieldname, val in self.get_default_address_and_contact("customer").items():
|
||||
if not self.doc.fields.get(fieldname) and self.meta.get_field(fieldname):
|
||||
self.doc.fields[fieldname] = val
|
||||
|
||||
# fetch missing item values
|
||||
for item in self.doclist.get({"parentfield": "entries"}):
|
||||
if item.fields.get("item_code"):
|
||||
ret = get_obj('Sales Common').get_item_details(item.fields, self)
|
||||
for fieldname, value in ret.items():
|
||||
if self.meta.get_field(fieldname, parentfield="entries") and \
|
||||
not item.fields.get(fieldname):
|
||||
item.fields[fieldname] = value
|
||||
def set_missing_values(self, for_validate=False):
|
||||
super(DocType, self).set_missing_values(for_validate)
|
||||
self.set_pos_fields(for_validate)
|
||||
|
||||
# fetch pos details, if they are not fetched
|
||||
if cint(self.doc.is_pos):
|
||||
self.set_pos_fields(for_validate=True)
|
||||
def set_customer_defaults(self):
|
||||
# TODO cleanup these methods
|
||||
self.doc.fields.update(self.get_debit_to())
|
||||
self.get_cust_and_due_date()
|
||||
|
||||
super(DocType, self).set_customer_defaults()
|
||||
|
||||
def update_time_log_batch(self, sales_invoice):
|
||||
for d in self.doclist.get({"doctype":"Sales Invoice Item"}):
|
||||
@@ -175,10 +166,11 @@ class DocType(SellingController):
|
||||
"""Set retail related fields from pos settings"""
|
||||
if cint(self.doc.is_pos) != 1:
|
||||
return
|
||||
|
||||
from selling.utils import get_pos_settings, apply_pos_settings
|
||||
pos = get_pos_settings(self.doc.company)
|
||||
|
||||
if self.pos_settings:
|
||||
pos = self.pos_settings[0]
|
||||
|
||||
if pos:
|
||||
self.doc.conversion_rate = flt(pos.conversion_rate)
|
||||
|
||||
if not self.doc.debit_to:
|
||||
@@ -191,11 +183,14 @@ class DocType(SellingController):
|
||||
'price_list_name', 'company', 'select_print_heading', 'cash_bank_account'):
|
||||
if (not for_validate) or (for_validate and not self.doc.fields.get(fieldname)):
|
||||
self.doc.fields[fieldname] = pos.get(fieldname)
|
||||
|
||||
if not for_validate:
|
||||
self.doc.update_stock = cint(pos.get("update_stock"))
|
||||
|
||||
# set pos values in items
|
||||
for item in self.doclist.get({"parentfield": "entries"}):
|
||||
if item.fields.get('item_code'):
|
||||
for fieldname, val in self.apply_pos_settings(item.fields).items():
|
||||
for fieldname, val in apply_pos_settings(pos, item.fields).items():
|
||||
if (not for_validate) or (for_validate and not item.fields.get(fieldname)):
|
||||
item.fields[fieldname] = val
|
||||
|
||||
@@ -205,7 +200,7 @@ class DocType(SellingController):
|
||||
|
||||
# fetch charges
|
||||
if self.doc.charge and not len(self.doclist.get({"parentfield": "other_charges"})):
|
||||
self.get_other_charges()
|
||||
self.set_taxes()
|
||||
|
||||
def get_customer_account(self):
|
||||
"""Get Account Head to which amount needs to be Debited based on Customer"""
|
||||
@@ -275,86 +270,6 @@ class DocType(SellingController):
|
||||
ret = self.get_debit_to()
|
||||
self.doc.debit_to = ret.get('debit_to')
|
||||
|
||||
|
||||
def load_default_accounts(self):
|
||||
"""
|
||||
Loads default accounts from items, customer when called from mapper
|
||||
"""
|
||||
self.get_income_expense_account('entries')
|
||||
|
||||
|
||||
def get_income_expense_account(self,doctype):
|
||||
for d in getlist(self.doclist, doctype):
|
||||
if d.item_code:
|
||||
item = webnotes.conn.get_value("Item", d.item_code, ["default_income_account",
|
||||
"default_sales_cost_center", "purchase_account"], as_dict=True)
|
||||
d.income_account = item['default_income_account'] or ""
|
||||
d.cost_center = item['default_sales_cost_center'] or ""
|
||||
|
||||
if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) \
|
||||
and cint(self.doc.is_pos) and cint(self.doc.update_stock):
|
||||
d.expense_account = item['purchase_account'] or ""
|
||||
|
||||
def get_item_details(self, args=None):
|
||||
import json
|
||||
args = args and json.loads(args) or {}
|
||||
if args.get('item_code'):
|
||||
ret = get_obj('Sales Common').get_item_details(args, self)
|
||||
|
||||
if cint(self.doc.is_pos) == 1 and self.pos_settings:
|
||||
ret = self.apply_pos_settings(args, ret)
|
||||
|
||||
return ret
|
||||
|
||||
elif cint(self.doc.is_pos) == 1 and self.pos_settings:
|
||||
for doc in self.doclist.get({"parentfield": "entries"}):
|
||||
if doc.fields.get('item_code'):
|
||||
ret = self.apply_pos_settings(doc.fields)
|
||||
for r in ret:
|
||||
if not doc.fields.get(r):
|
||||
doc.fields[r] = ret[r]
|
||||
|
||||
@property
|
||||
def pos_settings(self):
|
||||
if not hasattr(self, "_pos_settings"):
|
||||
dtl = webnotes.conn.sql("""select * from `tabPOS Setting` where user = %s
|
||||
and company = %s""", (webnotes.session['user'], self.doc.company), as_dict=1)
|
||||
if not dtl:
|
||||
dtl = webnotes.conn.sql("""select * from `tabPOS Setting`
|
||||
where ifnull(user,'') = '' and company = %s""", self.doc.company, as_dict=1)
|
||||
self._pos_settings = dtl
|
||||
|
||||
return self._pos_settings
|
||||
|
||||
def apply_pos_settings(self, args, ret=None):
|
||||
if not ret: ret = {}
|
||||
|
||||
pos = self.pos_settings[0]
|
||||
|
||||
item = webnotes.conn.sql("""select default_income_account, default_sales_cost_center,
|
||||
default_warehouse, purchase_account from tabItem where name = %s""",
|
||||
args.get('item_code'), as_dict=1)
|
||||
|
||||
if item:
|
||||
item = item[0]
|
||||
|
||||
ret.update({
|
||||
"income_account": item.get("default_income_account") \
|
||||
or pos.get("income_account") or args.get("income_account"),
|
||||
"cost_center": item.get("default_sales_cost_center") \
|
||||
or pos.get("cost_center") or args.get("cost_center"),
|
||||
"warehouse": item.get("default_warehouse") \
|
||||
or pos.get("warehouse") or args.get("warehouse"),
|
||||
"expense_account": item.get("purchase_account") \
|
||||
or pos.get("expense_account") or args.get("expense_account")
|
||||
})
|
||||
|
||||
if ret.get("warehouse"):
|
||||
ret["actual_qty"] = flt(webnotes.conn.get_value("Bin",
|
||||
{"item_code": args.get("item_code"), "warehouse": ret.get("warehouse")},
|
||||
"actual_qty"))
|
||||
return ret
|
||||
|
||||
def get_barcode_details(self, barcode):
|
||||
return get_obj('Sales Common').get_barcode_details(barcode)
|
||||
|
||||
@@ -378,14 +293,6 @@ class DocType(SellingController):
|
||||
return get_obj('Sales Common').get_tc_details(self)
|
||||
|
||||
|
||||
def load_default_taxes(self):
|
||||
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
||||
|
||||
|
||||
def get_other_charges(self):
|
||||
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
||||
|
||||
|
||||
def get_advances(self):
|
||||
super(DocType, self).get_advances(self.doc.debit_to,
|
||||
"Sales Invoice Advance", "advance_adjustment_details", "credit")
|
||||
@@ -534,13 +441,13 @@ class DocType(SellingController):
|
||||
def validate_item_code(self):
|
||||
for d in getlist(self.doclist, 'entries'):
|
||||
if not d.item_code:
|
||||
msgprint("Please enter Item Code at line no : %s to update stock for POS or remove check from Update Stock in Basic Info Tab." % (d.idx))
|
||||
raise Exception
|
||||
msgprint("Please enter Item Code at line no : %s to update stock or remove check from Update Stock in Basic Info Tab." % (d.idx),
|
||||
raise_exception=True)
|
||||
|
||||
def validate_delivery_note(self):
|
||||
for d in self.doclist.get({"parentfield": "entries"}):
|
||||
if d.delivery_note:
|
||||
msgprint("""POS can not be made against Delivery Note""", raise_exception=1)
|
||||
msgprint("""Stock update can not be made against Delivery Note""", raise_exception=1)
|
||||
|
||||
|
||||
def validate_write_off_account(self):
|
||||
@@ -606,36 +513,28 @@ class DocType(SellingController):
|
||||
|
||||
|
||||
def on_update(self):
|
||||
# Set default warehouse from pos setting
|
||||
if cint(self.doc.is_pos) == 1:
|
||||
if cint(self.doc.update_stock) == 1:
|
||||
if cint(self.doc.update_stock) == 1:
|
||||
# Set default warehouse from pos setting
|
||||
if cint(self.doc.is_pos) == 1:
|
||||
w = self.get_warehouse()
|
||||
if w:
|
||||
for d in getlist(self.doclist, 'entries'):
|
||||
if not d.warehouse:
|
||||
d.warehouse = cstr(w)
|
||||
|
||||
self.make_packing_list()
|
||||
else:
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
|
||||
|
||||
if flt(self.doc.paid_amount) == 0:
|
||||
if self.doc.cash_bank_account:
|
||||
webnotes.conn.set(self.doc, 'paid_amount',
|
||||
(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
|
||||
else:
|
||||
# show message that the amount is not paid
|
||||
webnotes.conn.set(self.doc,'paid_amount',0)
|
||||
webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
|
||||
if flt(self.doc.paid_amount) == 0:
|
||||
if self.doc.cash_bank_account:
|
||||
webnotes.conn.set(self.doc, 'paid_amount',
|
||||
(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
|
||||
else:
|
||||
# show message that the amount is not paid
|
||||
webnotes.conn.set(self.doc,'paid_amount',0)
|
||||
webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
|
||||
|
||||
self.make_packing_list()
|
||||
else:
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
|
||||
webnotes.conn.set(self.doc,'paid_amount',0)
|
||||
|
||||
webnotes.conn.set(self.doc, 'outstanding_amount',
|
||||
flt(self.doc.grand_total) - flt(self.doc.total_advance) -
|
||||
flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
|
||||
|
||||
|
||||
def check_prev_docstatus(self):
|
||||
for d in getlist(self.doclist,'entries'):
|
||||
@@ -689,15 +588,6 @@ class DocType(SellingController):
|
||||
|
||||
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)
|
||||
ret = {
|
||||
'actual_qty' : actual_qty and flt(actual_qty[0]['actual_qty']) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
def make_gl_entries(self):
|
||||
from accounts.general_ledger import make_gl_entries, merge_similar_entries
|
||||
|
||||
@@ -742,7 +632,7 @@ class DocType(SellingController):
|
||||
"against": self.doc.debit_to,
|
||||
"credit": flt(tax.tax_amount),
|
||||
"remarks": self.doc.remarks,
|
||||
"cost_center": tax.cost_center_other_charges
|
||||
"cost_center": tax.cost_center
|
||||
})
|
||||
)
|
||||
|
||||
@@ -762,7 +652,7 @@ class DocType(SellingController):
|
||||
|
||||
# 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):
|
||||
and cint(self.doc.update_stock):
|
||||
|
||||
for item in self.doclist.get({"parentfield": "entries"}):
|
||||
self.check_expense_account(item)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-04-19 11:00:14",
|
||||
"creation": "2013-05-24 19:29:05",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-04-22 11:59:28",
|
||||
"modified": "2013-05-29 18:53:26",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -10,6 +10,7 @@
|
||||
"allow_attach": 1,
|
||||
"autoname": "naming_series:",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Transaction",
|
||||
"is_submittable": 1,
|
||||
"module": "Accounts",
|
||||
"name": "__common__",
|
||||
@@ -79,7 +80,6 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_pos==1",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "update_stock",
|
||||
"fieldtype": "Check",
|
||||
@@ -118,10 +118,11 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "customer_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Name",
|
||||
"oldfieldname": "customer_name",
|
||||
@@ -129,34 +130,38 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "address_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Address",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Contact",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_mobile",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Mobile No",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_email",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"hidden": 0,
|
||||
"label": "Contact Email",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
@@ -222,11 +227,12 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "entries",
|
||||
"fieldtype": "Table",
|
||||
"label": "Entries",
|
||||
"label": "Sales Invoice Items",
|
||||
"oldfieldname": "entries",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Sales Invoice Item",
|
||||
"read_only": 0
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -250,35 +256,6 @@
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"description": "Will be calculated automatically when you enter the details",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total*",
|
||||
"oldfieldname": "net_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "recalculate_values",
|
||||
"fieldtype": "Button",
|
||||
"label": "Re-Calculate Values",
|
||||
"oldfieldtype": "Button",
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "col_break25",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"description": "Select Items from Sales Order",
|
||||
"doctype": "DocField",
|
||||
@@ -312,6 +289,43 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "col_break25",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "recalculate_values",
|
||||
"fieldtype": "Button",
|
||||
"label": "Re-Calculate Values",
|
||||
"oldfieldtype": "Button",
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total*",
|
||||
"oldfieldname": "net_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "net_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total (Export)",
|
||||
"options": "currency",
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "currency_section",
|
||||
@@ -450,6 +464,15 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "other_charges_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Taxes and Charges (Export)",
|
||||
"options": "currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "other_charges_calculation",
|
||||
@@ -728,6 +751,7 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_section",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -1283,6 +1307,17 @@
|
||||
"read_only": 0,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
@@ -1290,10 +1325,32 @@
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"match": "customer",
|
||||
@@ -1301,4 +1358,9 @@
|
||||
"report": 1,
|
||||
"role": "Customer"
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "Retail User"
|
||||
}
|
||||
]
|
||||
@@ -1,12 +1,226 @@
|
||||
import webnotes
|
||||
import unittest
|
||||
import unittest, json
|
||||
from webnotes.utils import flt, cint
|
||||
|
||||
class TestSalesInvoice(unittest.TestCase):
|
||||
def make(self):
|
||||
w = webnotes.bean(webnotes.copy_doclist(test_records[0]))
|
||||
w = webnotes.bean(copy=test_records[0])
|
||||
w.insert()
|
||||
w.submit()
|
||||
return w
|
||||
|
||||
def test_sales_invoice_calculation_base_currency(self):
|
||||
si = webnotes.bean(copy=test_records[2])
|
||||
si.run_method("calculate_taxes_and_totals")
|
||||
si.insert()
|
||||
|
||||
expected_values = {
|
||||
"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount",
|
||||
"base_ref_rate", "basic_rate", "amount"],
|
||||
"_Test Item Home Desktop 100": [50, 0, 50, 500, 50, 50, 500],
|
||||
"_Test Item Home Desktop 200": [150, 0, 150, 750, 150, 150, 750],
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
|
||||
len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.doclist.get({"parentfield": "entries"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.doc.net_total, 1250)
|
||||
self.assertEquals(si.doc.net_total_export, 1250)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
"keys": ["tax_amount", "total"],
|
||||
"_Test Account Shipping Charges - _TC": [100, 1350],
|
||||
"_Test Account Customs Duty - _TC": [125, 1475],
|
||||
"_Test Account Excise Duty - _TC": [140, 1615],
|
||||
"_Test Account Education Cess - _TC": [2.8, 1617.8],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1619.2],
|
||||
"_Test Account CST - _TC": [32.38, 1651.58],
|
||||
"_Test Account VAT - _TC": [156.25, 1807.83],
|
||||
"_Test Account Discount - _TC": [-180.78, 1627.05]
|
||||
}
|
||||
|
||||
for d in si.doclist.get({"parentfield": "other_charges"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.fields.get(k), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.doc.grand_total, 1627.05)
|
||||
self.assertEquals(si.doc.grand_total_export, 1627.05)
|
||||
|
||||
def test_sales_invoice_calculation_export_currency(self):
|
||||
si = webnotes.bean(copy=test_records[2])
|
||||
si.doc.currency = "USD"
|
||||
si.doc.conversion_rate = 50
|
||||
si.doclist[1].export_rate = 1
|
||||
si.doclist[1].ref_rate = 1
|
||||
si.doclist[2].export_rate = 3
|
||||
si.doclist[2].ref_rate = 3
|
||||
si.run_method("calculate_taxes_and_totals")
|
||||
si.insert()
|
||||
|
||||
expected_values = {
|
||||
"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount",
|
||||
"base_ref_rate", "basic_rate", "amount"],
|
||||
"_Test Item Home Desktop 100": [1, 0, 1, 10, 50, 50, 500],
|
||||
"_Test Item Home Desktop 200": [3, 0, 3, 15, 150, 150, 750],
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
|
||||
len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.doclist.get({"parentfield": "entries"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.doc.net_total, 1250)
|
||||
self.assertEquals(si.doc.net_total_export, 25)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
"keys": ["tax_amount", "total"],
|
||||
"_Test Account Shipping Charges - _TC": [100, 1350],
|
||||
"_Test Account Customs Duty - _TC": [125, 1475],
|
||||
"_Test Account Excise Duty - _TC": [140, 1615],
|
||||
"_Test Account Education Cess - _TC": [2.8, 1617.8],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1619.2],
|
||||
"_Test Account CST - _TC": [32.38, 1651.58],
|
||||
"_Test Account VAT - _TC": [156.25, 1807.83],
|
||||
"_Test Account Discount - _TC": [-180.78, 1627.05]
|
||||
}
|
||||
|
||||
for d in si.doclist.get({"parentfield": "other_charges"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.fields.get(k), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.doc.grand_total, 1627.05)
|
||||
self.assertEquals(si.doc.grand_total_export, 32.54)
|
||||
|
||||
def test_inclusive_rate_validations(self):
|
||||
si = webnotes.bean(copy=test_records[2])
|
||||
for i, tax in enumerate(si.doclist.get({"parentfield": "other_charges"})):
|
||||
tax.idx = i+1
|
||||
|
||||
si.doclist[1].ref_rate = 62.5
|
||||
si.doclist[1].ref_rate = 191
|
||||
for i in [3, 5, 6, 7, 8, 9]:
|
||||
si.doclist[i].included_in_print_rate = 1
|
||||
|
||||
# tax type "Actual" cannot be inclusive
|
||||
self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals")
|
||||
|
||||
# taxes above included type 'On Previous Row Total' should also be included
|
||||
si.doclist[3].included_in_print_rate = 0
|
||||
self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals")
|
||||
|
||||
def test_sales_invoice_calculation_base_currency_with_tax_inclusive_price(self):
|
||||
# prepare
|
||||
si = webnotes.bean(copy=test_records[3])
|
||||
si.run_method("calculate_taxes_and_totals")
|
||||
si.insert()
|
||||
|
||||
expected_values = {
|
||||
"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount",
|
||||
"base_ref_rate", "basic_rate", "amount"],
|
||||
"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 50, 50, 500],
|
||||
"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 150, 150, 750],
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
|
||||
len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.doclist.get({"parentfield": "entries"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.doc.net_total, 1250)
|
||||
self.assertEquals(si.doc.net_total_export, 1578.3)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
"keys": ["tax_amount", "total"],
|
||||
"_Test Account Excise Duty - _TC": [140, 1390],
|
||||
"_Test Account Education Cess - _TC": [2.8, 1392.8],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1394.2],
|
||||
"_Test Account CST - _TC": [27.88, 1422.08],
|
||||
"_Test Account VAT - _TC": [156.25, 1578.33],
|
||||
"_Test Account Customs Duty - _TC": [125, 1703.33],
|
||||
"_Test Account Shipping Charges - _TC": [100, 1803.33],
|
||||
"_Test Account Discount - _TC": [-180.33, 1623]
|
||||
}
|
||||
|
||||
for d in si.doclist.get({"parentfield": "other_charges"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.doc.grand_total, 1623)
|
||||
self.assertEquals(si.doc.grand_total_export, 1623)
|
||||
|
||||
def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
|
||||
# prepare
|
||||
si = webnotes.bean(copy=test_records[3])
|
||||
si.doc.currency = "USD"
|
||||
si.doc.conversion_rate = 50
|
||||
si.doclist[1].ref_rate = 55.56
|
||||
si.doclist[1].adj_rate = 10
|
||||
si.doclist[2].ref_rate = 187.5
|
||||
si.doclist[2].adj_rate = 20
|
||||
si.doclist[9].rate = 5000
|
||||
|
||||
si.run_method("calculate_taxes_and_totals")
|
||||
si.insert()
|
||||
|
||||
expected_values = {
|
||||
"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount",
|
||||
"base_ref_rate", "basic_rate", "amount"],
|
||||
"_Test Item Home Desktop 100": [55.56, 10, 50, 500, 2222.11, 1999.9, 19999.0],
|
||||
"_Test Item Home Desktop 200": [187.5, 20, 150, 750, 7375.66, 5900.53, 29502.65],
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
|
||||
len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.doclist.get({"parentfield": "entries"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.doc.net_total, 49501.65)
|
||||
self.assertEquals(si.doc.net_total_export, 1250)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
"keys": ["tax_amount", "total"],
|
||||
"_Test Account Excise Duty - _TC": [5540.22, 55041.87],
|
||||
"_Test Account Education Cess - _TC": [110.81, 55152.68],
|
||||
"_Test Account S&H Education Cess - _TC": [55.4, 55208.08],
|
||||
"_Test Account CST - _TC": [1104.16, 56312.24],
|
||||
"_Test Account VAT - _TC": [6187.71, 62499.95],
|
||||
"_Test Account Customs Duty - _TC": [4950.17, 67450.12],
|
||||
"_Test Account Shipping Charges - _TC": [5000, 72450.12],
|
||||
"_Test Account Discount - _TC": [-7245.01, 65205.11]
|
||||
}
|
||||
|
||||
for d in si.doclist.get({"parentfield": "other_charges"}):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.doc.grand_total, 65205.11)
|
||||
self.assertEquals(si.doc.grand_total_export, 1304.1)
|
||||
|
||||
def test_outstanding(self):
|
||||
w = self.make()
|
||||
@@ -103,7 +317,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
pos[0]["cash_bank_account"] = "_Test Account Bank Account - _TC"
|
||||
pos[0]["paid_amount"] = 600.0
|
||||
|
||||
si = webnotes.bean(pos)
|
||||
si = webnotes.bean(copy=pos)
|
||||
si.insert()
|
||||
si.submit()
|
||||
|
||||
@@ -113,7 +327,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
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])
|
||||
["_Test Item", "_Test Warehouse", -1.0])
|
||||
|
||||
# check gl entries
|
||||
stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
|
||||
@@ -126,11 +340,11 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
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],
|
||||
[pos[1]["income_account"], 0.0, 500.0],
|
||||
[pos[2]["account_head"], 0.0, 80.0],
|
||||
[pos[3]["account_head"], 0.0, 50.0],
|
||||
[stock_in_hand_account, 0.0, 75.0],
|
||||
[pos[1]["expense_account"], 75.0, 0.0],
|
||||
[si.doc.debit_to, 0.0, 600.0],
|
||||
["_Test Account Bank Account - _TC", 600.0, 0.0]
|
||||
])
|
||||
@@ -444,7 +658,7 @@ test_records = [
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"tax_amount": 30.0,
|
||||
"rate": 6,
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
@@ -452,7 +666,7 @@ test_records = [
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"tax_amount": 31.8,
|
||||
"rate": 6.36,
|
||||
},
|
||||
{
|
||||
"parentfield": "sales_team",
|
||||
@@ -494,7 +708,7 @@ test_records = [
|
||||
"description": "_Test Item",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"parentfield": "entries",
|
||||
"qty": 5.0,
|
||||
"qty": 1.0,
|
||||
"basic_rate": 500.0,
|
||||
"amount": 500.0,
|
||||
"export_rate": 500.0,
|
||||
@@ -509,7 +723,7 @@ test_records = [
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"tax_amount": 80.0,
|
||||
"rate": 16,
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
@@ -517,7 +731,270 @@ test_records = [
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"tax_amount": 50.0,
|
||||
"rate": 10
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"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_export": 0,
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
"price_list_name": "_Test Price List",
|
||||
"territory": "_Test Territory",
|
||||
},
|
||||
# items
|
||||
{
|
||||
"doctype": "Sales Invoice Item",
|
||||
"parentfield": "entries",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"qty": 10,
|
||||
"ref_rate": 50,
|
||||
"export_rate": 50,
|
||||
"stock_uom": "_Test UOM",
|
||||
"item_tax_rate": json.dumps({"_Test Account Excise Duty - _TC": 10}),
|
||||
"income_account": "Sales - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Invoice Item",
|
||||
"parentfield": "entries",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"qty": 5,
|
||||
"ref_rate": 150,
|
||||
"export_rate": 150,
|
||||
"stock_uom": "_Test UOM",
|
||||
"income_account": "Sales - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
|
||||
},
|
||||
# taxes
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "Actual",
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"rate": 100
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"rate": 10
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"rate": 12
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"rate": 2,
|
||||
"row_id": 3
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"rate": 1,
|
||||
"row_id": 3
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"rate": 2,
|
||||
"row_id": 5
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"rate": 12.5
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"rate": -10,
|
||||
"row_id": 7
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
"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_export": 0,
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
"price_list_name": "_Test Price List",
|
||||
"territory": "_Test Territory",
|
||||
},
|
||||
# items
|
||||
{
|
||||
"doctype": "Sales Invoice Item",
|
||||
"parentfield": "entries",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"qty": 10,
|
||||
"ref_rate": 62.5,
|
||||
"export_rate": 62.5,
|
||||
"stock_uom": "_Test UOM",
|
||||
"item_tax_rate": json.dumps({"_Test Account Excise Duty - _TC": 10}),
|
||||
"income_account": "Sales - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Invoice Item",
|
||||
"parentfield": "entries",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"qty": 5,
|
||||
"ref_rate": 190.66,
|
||||
"export_rate": 190.66,
|
||||
"stock_uom": "_Test UOM",
|
||||
"income_account": "Sales - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
|
||||
},
|
||||
# taxes
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"rate": 12,
|
||||
"included_in_print_rate": 1,
|
||||
"idx": 1
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"rate": 2,
|
||||
"row_id": 1,
|
||||
"included_in_print_rate": 1,
|
||||
"idx": 2
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"rate": 1,
|
||||
"row_id": 1,
|
||||
"included_in_print_rate": 1,
|
||||
"idx": 3
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"rate": 2,
|
||||
"row_id": 3,
|
||||
"included_in_print_rate": 1,
|
||||
"idx": 4
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"rate": 12.5,
|
||||
"included_in_print_rate": 1,
|
||||
"idx": 5
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"rate": 10,
|
||||
"idx": 6
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "Actual",
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"rate": 100,
|
||||
"idx": 7
|
||||
},
|
||||
{
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"rate": -10,
|
||||
"row_id": 7,
|
||||
"idx": 8
|
||||
},
|
||||
],
|
||||
]
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-04-19 11:00:07",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-22 12:06:15",
|
||||
"modified": "2013-05-22 12:07:00",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
@@ -163,7 +163,7 @@
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-02-22 01:27:41",
|
||||
"creation": "2013-04-24 11:39:32",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-04-17 14:05:18",
|
||||
"modified": "2013-05-28 11:59:02",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -50,7 +50,7 @@
|
||||
{
|
||||
"default": ":Company",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "cost_center_other_charges",
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center_other_charges",
|
||||
@@ -85,6 +85,7 @@
|
||||
"oldfieldname": "tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
@@ -128,34 +129,6 @@
|
||||
"print_hide": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"description": "Cheating Field\nPlease do not delete ",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "total_tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Total Tax Amount",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "total_tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"description": "Cheating Field\nPlease do not delete ",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Total Amount",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "total_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"description": "If checked, the tax amount will be considered as already included in the Print Rate / Print Amount",
|
||||
|
||||
@@ -140,7 +140,7 @@ cur_frm.fields_dict['other_charges'].grid.get_field("account_head").get_query =
|
||||
return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus != 2 AND tabAccount.account_type in ("Tax", "Chargeable", "Income Account") AND tabAccount.company = "'+doc.company+'" AND tabAccount.name LIKE "%s"'
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['other_charges'].grid.get_field("cost_center_other_charges").get_query = function(doc) {
|
||||
cur_frm.fields_dict['other_charges'].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';
|
||||
}
|
||||
|
||||
|
||||
1
accounts/page/accounts_browser/README.md
Normal file
1
accounts/page/accounts_browser/README.md
Normal file
@@ -0,0 +1 @@
|
||||
Tree view browser for Chart of Accounts and Chart of Cost Centers
|
||||
@@ -1,18 +0,0 @@
|
||||
<div class="layout-wrapper layout-wrapper-background">
|
||||
<div class="appframe-area"></div>
|
||||
<div class="layout-main">
|
||||
<div class="tree-area"></div>
|
||||
<hr>
|
||||
<div class="well">
|
||||
<h4>Quick Help</h4>
|
||||
<ol>
|
||||
<li>To add child nodes, explore tree and click on the node under which you want to add more nodes.
|
||||
<li>Accounting Entries can be made against leaf nodes, called <b>Ledgers</b>. Entries against <b>Groups</b> are not allowed.
|
||||
<li>Please do NOT create Account (Ledgers) for Customers and Suppliers. They are created directly from the Customer / Supplier masters.
|
||||
<li><b>To create a Bank Account:</b> Go to the appropriate group (usually Application of Funds > Current Assets > Bank Accounts) and create a new Account Ledger (by clicking on Add Child) of type "Bank or Cash"
|
||||
<li><b>To create a Tax Account:</b> Go to the appropriate group (usually Source of Funds > Current Liabilities > Taxes and Duties) and create a new Account Ledger (by clicking on Add Child) of type "Tax" and do mention the Tax rate.
|
||||
</ol>
|
||||
<p>Please setup your chart of accounts before you start Accounting Entries</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,9 +21,37 @@
|
||||
// see ledger
|
||||
|
||||
pscript['onload_Accounts Browser'] = function(wrapper){
|
||||
wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'));
|
||||
wrapper.appframe.add_home_breadcrumb()
|
||||
wrapper.appframe.add_module_breadcrumb("Accounts")
|
||||
wn.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
single_column: true
|
||||
})
|
||||
|
||||
wrapper.appframe.add_module_icon("Accounts");
|
||||
|
||||
var main = $(wrapper).find(".layout-main"),
|
||||
chart_area = $("<div>")
|
||||
.css({"margin-bottom": "15px"})
|
||||
.appendTo(main),
|
||||
help_area = $('<div class="well">\
|
||||
<h4>Quick Help</h4>\
|
||||
<ol>\
|
||||
<li>To add child nodes, explore tree and click on the node under which you \
|
||||
want to add more nodes.\
|
||||
<li>Accounting Entries can be made against leaf nodes, called <b>Ledgers</b>.\
|
||||
Entries against <b>Groups</b> are not allowed.\
|
||||
<li>Please do NOT create Account (Ledgers) for Customers and Suppliers. \
|
||||
They are created directly from the Customer / Supplier masters.\
|
||||
<li><b>To create a Bank Account:</b> Go to the appropriate group \
|
||||
(usually Application of Funds > Current Assets > Bank Accounts)\
|
||||
and create a new Account Ledger (by clicking on Add Child) of \
|
||||
type "Bank or Cash"\
|
||||
<li><b>To create a Tax Account:</b> Go to the appropriate group \
|
||||
(usually Source of Funds > Current Liabilities > Taxes and Duties) \
|
||||
and create a new Account Ledger (by clicking on Add Child) of type\
|
||||
"Tax" and do mention the Tax rate.\
|
||||
</ol>\
|
||||
<p>Please setup your chart of accounts before you start Accounting Entries</p>\
|
||||
</div>').appendTo(main);
|
||||
|
||||
if (wn.boot.profile.can_create.indexOf("Company") !== -1) {
|
||||
wrapper.appframe.add_button('New Company', function() { newdoc('Company'); },
|
||||
@@ -35,13 +63,13 @@ pscript['onload_Accounts Browser'] = function(wrapper){
|
||||
}, 'icon-refresh');
|
||||
|
||||
// company-select
|
||||
wrapper.$company_select = $('<select class="accbrowser-company-select"></select>')
|
||||
wrapper.$company_select = wrapper.appframe.add_select("Company", [])
|
||||
.change(function() {
|
||||
var ctype = wn.get_route()[1] || 'Account';
|
||||
erpnext.account_chart = new erpnext.AccountsChart(ctype, $(this).val(), wrapper);
|
||||
erpnext.account_chart = new erpnext.AccountsChart(ctype, $(this).val(),
|
||||
chart_area.get(0));
|
||||
pscript.set_title(wrapper, ctype, $(this).val());
|
||||
})
|
||||
.appendTo(wrapper.appframe.$w.find('.appframe-toolbar'));
|
||||
|
||||
// load up companies
|
||||
wn.call({
|
||||
@@ -77,7 +105,7 @@ pscript['onshow_Accounts Browser'] = function(wrapper){
|
||||
|
||||
erpnext.AccountsChart = Class.extend({
|
||||
init: function(ctype, company, wrapper) {
|
||||
$(wrapper).find('.tree-area').empty();
|
||||
$(wrapper).empty();
|
||||
var me = this;
|
||||
me.ctype = ctype;
|
||||
me.can_create = wn.model.can_create(this.ctype);
|
||||
@@ -87,7 +115,7 @@ erpnext.AccountsChart = Class.extend({
|
||||
|
||||
me.company = company;
|
||||
this.tree = new wn.ui.Tree({
|
||||
parent: $(wrapper).find('.tree-area'),
|
||||
parent: $(wrapper),
|
||||
label: company,
|
||||
args: {ctype: ctype, comp: company},
|
||||
method: 'accounts.page.accounts_browser.accounts_browser.get_children',
|
||||
|
||||
@@ -25,7 +25,7 @@ wn.pages['financial-analytics'].onload = function(wrapper) {
|
||||
erpnext.trial_balance = new erpnext.FinancialAnalytics(wrapper, 'Financial Analytics');
|
||||
|
||||
wrapper.appframe.add_home_breadcrumb()
|
||||
wrapper.appframe.add_module_breadcrumb("Accounts")
|
||||
wrapper.appframe.add_module_icon("Accounts")
|
||||
wrapper.appframe.add_breadcrumb("icon-bar-chart")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,5 @@
|
||||
<div class="layout_wrapper">
|
||||
<div class="appframe col col-lg-12">
|
||||
<div id="fs_header"></div>
|
||||
<!-- table.statement td { vertical-align: middle; } table.statement td select { width: 100px; } table.stmt_table { table-layout: fixed; border-collapse: collapse; } table.stmt_table td { vertical-align: middle; padding: 2px; } td.stmt_level0 { font-weight: bold; font-size: 14px; border-bottom: 1px solid #AAA; } td.stmt_level1 { font-weight: bold; font-size: 12px; } td.stmt_level2 { font-size: 11px; } td.stmt_level3 { font-size: 11px; } td.stmt_level4 { font-size: 12px; font-weight: bold; border-bottom: 1px solid #000; } td.stmt_level5 { color: BLUE; font-size: 11px; } --> <!--
|
||||
<div style="border: 1px solid #cccccc; padding: 4px; margin-top: 8px; background-color: #eeeeee; width: 98%;">
|
||||
<table class="statement" border="0" cellspacing="2px">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Statement:</td>
|
||||
<td style="padding-right: 8px;" mce_style="padding-right: 8px;"><select id="stmt_type"></select></td>
|
||||
<td>Company:</td>
|
||||
<td style="padding-right: 8px;" mce_style="padding-right: 8px;"><select id="stmt_company"></select></td>
|
||||
<td>Period Type:</td>
|
||||
<td style="padding-right: 8px;" mce_style="padding-right: 8px;"><select id="stmt_period"></select></td>
|
||||
<td>Fiscal Year:</td>
|
||||
<td style="padding-right: 8px;" mce_style="padding-right: 8px;"><select id="stmt_fiscal_year"></select></td>
|
||||
<td style="padding-right: 8px;" mce_style="padding-right: 8px;">
|
||||
<div id="stmt_new"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
--> <!--
|
||||
<div style="margin:10px 0px 10px 0px" mce_style="margin:10px 0px 10px 0px"><button class="button" onclick="pscript.print_statement();">Print</button></div>
|
||||
-->
|
||||
<div id="print_html">
|
||||
<div id="stmt_title1" style="margin:16px 0px 4px 0px; font-size: 16px; font-weight: bold; color: #888;"></div>
|
||||
<div id="stmt_title2" style="margin:0px 0px 8px 0px; font-size: 16px; font-weight: bold;"></div>
|
||||
|
||||
@@ -24,7 +24,7 @@ wn.pages['general-ledger'].onload = function(wrapper) {
|
||||
erpnext.general_ledger = new erpnext.GeneralLedger(wrapper);
|
||||
|
||||
wrapper.appframe.add_home_breadcrumb()
|
||||
wrapper.appframe.add_module_breadcrumb("Accounts")
|
||||
wrapper.appframe.add_module_icon("Accounts")
|
||||
wrapper.appframe.add_breadcrumb("icon-bar-chart")
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,6 @@ wn.pages['trial-balance'].onload = function(wrapper) {
|
||||
erpnext.trial_balance = new TrialBalance(wrapper, 'Trial Balance');
|
||||
|
||||
wrapper.appframe.add_home_breadcrumb()
|
||||
wrapper.appframe.add_module_breadcrumb("Accounts")
|
||||
wrapper.appframe.add_module_icon("Accounts")
|
||||
wrapper.appframe.add_breadcrumb("icon-bar-chart")
|
||||
}
|
||||
@@ -92,7 +92,7 @@ def get_source_data(filters):
|
||||
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
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user