Fixed conflict while merging with develop brnach
This commit is contained in:
commit
dc15b4fa8a
File diff suppressed because one or more lines are too long
@ -6,6 +6,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import _
|
from webnotes import _
|
||||||
|
from webnotes.utils import cint
|
||||||
|
|
||||||
class DocType:
|
class DocType:
|
||||||
def __init__(self, d, dl):
|
def __init__(self, d, dl):
|
||||||
@ -14,7 +15,12 @@ class DocType:
|
|||||||
def on_update(self):
|
def on_update(self):
|
||||||
webnotes.conn.set_default("auto_accounting_for_stock", self.doc.auto_accounting_for_stock)
|
webnotes.conn.set_default("auto_accounting_for_stock", self.doc.auto_accounting_for_stock)
|
||||||
|
|
||||||
if self.doc.auto_accounting_for_stock:
|
if cint(self.doc.auto_accounting_for_stock):
|
||||||
|
# set default perpetual account in company
|
||||||
|
for company in webnotes.conn.sql("select name from tabCompany"):
|
||||||
|
webnotes.bean("Company", company[0]).save()
|
||||||
|
|
||||||
|
# Create account head for warehouses
|
||||||
warehouse_list = webnotes.conn.sql("select name, company from tabWarehouse", as_dict=1)
|
warehouse_list = webnotes.conn.sql("select name, company from tabWarehouse", as_dict=1)
|
||||||
warehouse_with_no_company = [d.name for d in warehouse_list if not d.company]
|
warehouse_with_no_company = [d.name for d in warehouse_list if not d.company]
|
||||||
if warehouse_with_no_company:
|
if warehouse_with_no_company:
|
||||||
|
@ -146,11 +146,12 @@ def update_outstanding_amt(account, against_voucher_type, against_voucher, on_ca
|
|||||||
webnotes.conn.sql("update `tab%s` set outstanding_amount=%s where name='%s'" %
|
webnotes.conn.sql("update `tab%s` set outstanding_amount=%s where name='%s'" %
|
||||||
(against_voucher_type, bal, against_voucher))
|
(against_voucher_type, bal, against_voucher))
|
||||||
|
|
||||||
def validate_frozen_account(account, adv_adj):
|
def validate_frozen_account(account, adv_adj=None):
|
||||||
frozen_account = webnotes.conn.get_value("Account", account, "freeze_account")
|
frozen_account = webnotes.conn.get_value("Account", account, "freeze_account")
|
||||||
if frozen_account == 'Yes' and not adv_adj:
|
if frozen_account == 'Yes' and not adv_adj:
|
||||||
frozen_accounts_modifier = webnotes.conn.get_value( 'Accounts Settings', None,
|
frozen_accounts_modifier = webnotes.conn.get_value( 'Accounts Settings', None,
|
||||||
'frozen_accounts_modifier')
|
'frozen_accounts_modifier')
|
||||||
|
|
||||||
if not frozen_accounts_modifier:
|
if not frozen_accounts_modifier:
|
||||||
webnotes.throw(account + _(" is a frozen account. Either make the account active or assign role in Accounts Settings who can create / modify entries against this account"))
|
webnotes.throw(account + _(" is a frozen account. Either make the account active or assign role in Accounts Settings who can create / modify entries against this account"))
|
||||||
elif frozen_accounts_modifier not in webnotes.user.get_roles():
|
elif frozen_accounts_modifier not in webnotes.user.get_roles():
|
||||||
|
@ -120,7 +120,8 @@ cur_frm.cscript.refresh = function(doc) {
|
|||||||
"voucher_no": doc.name,
|
"voucher_no": doc.name,
|
||||||
"from_date": doc.posting_date,
|
"from_date": doc.posting_date,
|
||||||
"to_date": doc.posting_date,
|
"to_date": doc.posting_date,
|
||||||
"company": doc.company
|
"company": doc.company,
|
||||||
|
group_by_voucher: 0
|
||||||
};
|
};
|
||||||
wn.set_route("query-report", "General Ledger");
|
wn.set_route("query-report", "General Ledger");
|
||||||
}, "icon-table");
|
}, "icon-table");
|
||||||
|
@ -140,13 +140,13 @@ def gl_entry_details(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
and ifnull(gle.%(account_type)s, 0) > 0
|
and ifnull(gle.%(account_type)s, 0) > 0
|
||||||
and (select ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0)
|
and (select ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0)
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where against_voucher_type = '%(dt)s'
|
where account = '%(acc)s'
|
||||||
|
and against_voucher_type = '%(dt)s'
|
||||||
and against_voucher = gle.voucher_no
|
and against_voucher = gle.voucher_no
|
||||||
and voucher_no != gle.voucher_no)
|
and voucher_no != gle.voucher_no)
|
||||||
!= abs(ifnull(gle.debit, 0) - ifnull(gle.credit, 0)
|
!= abs(ifnull(gle.debit, 0) - ifnull(gle.credit, 0))
|
||||||
)
|
and if(gle.voucher_type='Sales Invoice', ifnull((select is_pos from `tabSales Invoice`
|
||||||
and if(gle.voucher_type='Sales Invoice', (select is_pos from `tabSales Invoice`
|
where name=gle.voucher_no), 0), 0)=0
|
||||||
where name=gle.voucher_no), 0)=0
|
|
||||||
%(mcond)s
|
%(mcond)s
|
||||||
ORDER BY gle.posting_date desc, gle.voucher_no desc
|
ORDER BY gle.posting_date desc, gle.voucher_no desc
|
||||||
limit %(start)s, %(page_len)s""" % {
|
limit %(start)s, %(page_len)s""" % {
|
||||||
|
@ -7,7 +7,7 @@ cur_frm.cscript.onload = function(doc,cdt,cdn){
|
|||||||
});
|
});
|
||||||
|
|
||||||
cur_frm.set_query("selling_price_list", function() {
|
cur_frm.set_query("selling_price_list", function() {
|
||||||
return { filters: { buying_or_selling: "Selling" } };
|
return { filters: { selling: 1 } };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-05-24 12:15:51",
|
"creation": "2013-05-24 12:15:51",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 19:24:16",
|
"modified": "2014-01-15 16:23:58",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -156,7 +156,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
|
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "expense_account",
|
"fieldname": "expense_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
@ -35,7 +35,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
"voucher_no": doc.name,
|
"voucher_no": doc.name,
|
||||||
"from_date": doc.posting_date,
|
"from_date": doc.posting_date,
|
||||||
"to_date": doc.posting_date,
|
"to_date": doc.posting_date,
|
||||||
"company": doc.company
|
"company": doc.company,
|
||||||
|
group_by_voucher: 0
|
||||||
};
|
};
|
||||||
wn.set_route("query-report", "General Ledger");
|
wn.set_route("query-report", "General Ledger");
|
||||||
}, "icon-table");
|
}, "icon-table");
|
||||||
|
@ -302,6 +302,7 @@ class DocType(BuyingController):
|
|||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
self.update_against_document_in_jv()
|
self.update_against_document_in_jv()
|
||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||||
|
|
||||||
def make_gl_entries(self):
|
def make_gl_entries(self):
|
||||||
auto_accounting_for_stock = \
|
auto_accounting_for_stock = \
|
||||||
@ -350,7 +351,6 @@ class DocType(BuyingController):
|
|||||||
# item gl entries
|
# item gl entries
|
||||||
stock_item_and_auto_accounting_for_stock = False
|
stock_item_and_auto_accounting_for_stock = False
|
||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
# rounding_diff = 0.0
|
|
||||||
for item in self.doclist.get({"parentfield": "entries"}):
|
for item in self.doclist.get({"parentfield": "entries"}):
|
||||||
if auto_accounting_for_stock and item.item_code in stock_items:
|
if auto_accounting_for_stock and item.item_code in stock_items:
|
||||||
if flt(item.valuation_rate):
|
if flt(item.valuation_rate):
|
||||||
@ -359,12 +359,8 @@ class DocType(BuyingController):
|
|||||||
# expense will be booked in sales invoice
|
# expense will be booked in sales invoice
|
||||||
stock_item_and_auto_accounting_for_stock = True
|
stock_item_and_auto_accounting_for_stock = True
|
||||||
|
|
||||||
valuation_amt = item.amount + item.item_tax_amount + item.rm_supp_cost
|
valuation_amt = flt(item.amount + item.item_tax_amount + item.rm_supp_cost,
|
||||||
|
self.precision("amount", item))
|
||||||
# rounding_diff += (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)) -
|
|
||||||
# valuation_amt)
|
|
||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
@ -393,12 +389,6 @@ class DocType(BuyingController):
|
|||||||
expenses_included_in_valuation = \
|
expenses_included_in_valuation = \
|
||||||
self.get_company_default("expenses_included_in_valuation")
|
self.get_company_default("expenses_included_in_valuation")
|
||||||
|
|
||||||
# if rounding_diff:
|
|
||||||
# import operator
|
|
||||||
# cost_center_with_max_value = max(valuation_tax.iteritems(),
|
|
||||||
# key=operator.itemgetter(1))[0]
|
|
||||||
# valuation_tax[cost_center_with_max_value] -= flt(rounding_diff)
|
|
||||||
|
|
||||||
for cost_center, amount in valuation_tax.items():
|
for cost_center, amount in valuation_tax.items():
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
@ -432,7 +422,7 @@ class DocType(BuyingController):
|
|||||||
remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_voucher")
|
remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_voucher")
|
||||||
|
|
||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||||
self.make_cancel_gl_entries()
|
self.make_cancel_gl_entries()
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
|
@ -19,8 +19,10 @@ erpnext.POS = Class.extend({
|
|||||||
<table class="table table-condensed table-hover" id="cart" style="table-layout: fixed;">\
|
<table class="table table-condensed table-hover" id="cart" style="table-layout: fixed;">\
|
||||||
<thead>\
|
<thead>\
|
||||||
<tr>\
|
<tr>\
|
||||||
<th style="width: 50%">Item</th>\
|
<th style="width: 40%">Item</th>\
|
||||||
<th style="width: 25%; text-align: right;">Qty</th>\
|
<th style="width: 9%"></th>\
|
||||||
|
<th style="width: 17%; text-align: right;">Qty</th>\
|
||||||
|
<th style="width: 9%"></th>\
|
||||||
<th style="width: 25%; text-align: right;">Rate</th>\
|
<th style="width: 25%; text-align: right;">Rate</th>\
|
||||||
</tr>\
|
</tr>\
|
||||||
</thead>\
|
</thead>\
|
||||||
@ -60,10 +62,16 @@ erpnext.POS = Class.extend({
|
|||||||
</div>\
|
</div>\
|
||||||
</div>\
|
</div>\
|
||||||
<br><br>\
|
<br><br>\
|
||||||
<button class="btn btn-success btn-lg make-payment">\
|
<div class="row">\
|
||||||
<i class="icon-money"></i> Make Payment</button>\
|
<div class="col-sm-9">\
|
||||||
<button class="btn btn-default btn-lg delete-items pull-right" style="display: none;">\
|
<button class="btn btn-success btn-lg make-payment">\
|
||||||
<i class="icon-trash"></i> Del</button>\
|
<i class="icon-money"></i> Make Payment</button>\
|
||||||
|
</div>\
|
||||||
|
<div class="col-sm-3">\
|
||||||
|
<button class="btn btn-default btn-lg remove-items" style="display: none;">\
|
||||||
|
<i class="icon-trash"></i> Del</button>\
|
||||||
|
</div>\
|
||||||
|
</div>\
|
||||||
<br><br>\
|
<br><br>\
|
||||||
</div>\
|
</div>\
|
||||||
<div class="col-sm-6">\
|
<div class="col-sm-6">\
|
||||||
@ -82,7 +90,7 @@ erpnext.POS = Class.extend({
|
|||||||
me.refresh();
|
me.refresh();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.call_function("delete-items", function() {me.remove_selected_item();});
|
this.call_function("remove-items", function() {me.remove_selected_items();});
|
||||||
this.call_function("make-payment", function() {me.make_payment();});
|
this.call_function("make-payment", function() {me.make_payment();});
|
||||||
},
|
},
|
||||||
check_transaction_type: function() {
|
check_transaction_type: function() {
|
||||||
@ -333,7 +341,7 @@ erpnext.POS = Class.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.disable_text_box_and_button();
|
this.disable_text_box_and_button();
|
||||||
this.make_payment_button();
|
this.hide_payment_button();
|
||||||
|
|
||||||
// If quotation to is not Customer then remove party
|
// If quotation to is not Customer then remove party
|
||||||
if (this.frm.doctype == "Quotation") {
|
if (this.frm.doctype == "Quotation") {
|
||||||
@ -351,8 +359,18 @@ erpnext.POS = Class.extend({
|
|||||||
|
|
||||||
$(repl('<tr id="%(item_code)s" data-selected="false">\
|
$(repl('<tr id="%(item_code)s" data-selected="false">\
|
||||||
<td>%(item_code)s%(item_name)s</td>\
|
<td>%(item_code)s%(item_name)s</td>\
|
||||||
<td><input type="text" value="%(qty)s" \
|
<td style="vertical-align:middle;" align="right">\
|
||||||
|
<div class="decrease-qty" style="cursor:pointer;">\
|
||||||
|
<i class="icon-minus-sign icon-large text-danger"></i>\
|
||||||
|
</div>\
|
||||||
|
</td>\
|
||||||
|
<td style="vertical-align:middle;"><input type="text" value="%(qty)s" \
|
||||||
class="form-control qty" style="text-align: right;"></td>\
|
class="form-control qty" style="text-align: right;"></td>\
|
||||||
|
<td style="vertical-align:middle;cursor:pointer;">\
|
||||||
|
<div class="increase-qty" style="cursor:pointer;">\
|
||||||
|
<i class="icon-plus-sign icon-large text-success"></i>\
|
||||||
|
</div>\
|
||||||
|
</td>\
|
||||||
<td style="text-align: right;"><b>%(amount)s</b><br>%(rate)s</td>\
|
<td style="text-align: right;"><b>%(amount)s</b><br>%(rate)s</td>\
|
||||||
</tr>',
|
</tr>',
|
||||||
{
|
{
|
||||||
@ -364,27 +382,32 @@ erpnext.POS = Class.extend({
|
|||||||
}
|
}
|
||||||
)).appendTo($items);
|
)).appendTo($items);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.wrapper.find(".increase-qty, .decrease-qty").on("click", function() {
|
||||||
|
var item_code = $(this).closest("tr").attr("id");
|
||||||
|
me.selected_item_qty_operation(item_code, $(this).attr("class"));
|
||||||
|
});
|
||||||
},
|
},
|
||||||
show_taxes: function() {
|
show_taxes: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges",
|
var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges",
|
||||||
this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype);
|
this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype);
|
||||||
$(this.wrapper).find(".tax-table")
|
$(this.wrapper).find(".tax-table")
|
||||||
.toggle((taxes && taxes.length &&
|
.toggle((taxes && taxes.length) ? true : false)
|
||||||
flt(me.frm.doc.other_charges_total_export ||
|
|
||||||
me.frm.doc.other_charges_added_import) != 0.0) ? true : false)
|
|
||||||
.find("tbody").empty();
|
.find("tbody").empty();
|
||||||
|
|
||||||
$.each(taxes, function(i, d) {
|
$.each(taxes, function(i, d) {
|
||||||
$(repl('<tr>\
|
if (d.tax_amount) {
|
||||||
<td>%(description)s %(rate)s</td>\
|
$(repl('<tr>\
|
||||||
<td style="text-align: right;">%(tax_amount)s</td>\
|
<td>%(description)s %(rate)s</td>\
|
||||||
<tr>', {
|
<td style="text-align: right;">%(tax_amount)s</td>\
|
||||||
description: d.description,
|
<tr>', {
|
||||||
rate: ((d.charge_type == "Actual") ? '' : ("(" + d.rate + "%)")),
|
description: d.description,
|
||||||
tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate),
|
rate: ((d.charge_type == "Actual") ? '' : ("(" + d.rate + "%)")),
|
||||||
me.frm.doc.currency)
|
tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate),
|
||||||
})).appendTo(".tax-table tbody");
|
me.frm.doc.currency)
|
||||||
|
})).appendTo(".tax-table tbody");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
set_totals: function() {
|
set_totals: function() {
|
||||||
@ -427,7 +450,7 @@ erpnext.POS = Class.extend({
|
|||||||
$(this.wrapper).find('input, button').each(function () {
|
$(this.wrapper).find('input, button').each(function () {
|
||||||
$(this).prop('disabled', true);
|
$(this).prop('disabled', true);
|
||||||
});
|
});
|
||||||
$(this.wrapper).find(".delete-items").hide();
|
$(this.wrapper).find(".remove-items").hide();
|
||||||
$(this.wrapper).find(".make-payment").hide();
|
$(this.wrapper).find(".make-payment").hide();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -437,14 +460,14 @@ erpnext.POS = Class.extend({
|
|||||||
$(this.wrapper).find(".make-payment").show();
|
$(this.wrapper).find(".make-payment").show();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
make_payment_button: function() {
|
hide_payment_button: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
// Show Make Payment button only in Sales Invoice
|
// Show Make Payment button only in Sales Invoice
|
||||||
if (this.frm.doctype != "Sales Invoice")
|
if (this.frm.doctype != "Sales Invoice")
|
||||||
$(this.wrapper).find(".make-payment").hide();
|
$(this.wrapper).find(".make-payment").hide();
|
||||||
},
|
},
|
||||||
refresh_delete_btn: function() {
|
refresh_delete_btn: function() {
|
||||||
$(this.wrapper).find(".delete-items").toggle($(".item-cart .warning").length ? true : false);
|
$(this.wrapper).find(".remove-items").toggle($(".item-cart .warning").length ? true : false);
|
||||||
},
|
},
|
||||||
add_item_thru_barcode: function() {
|
add_item_thru_barcode: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
@ -466,7 +489,7 @@ erpnext.POS = Class.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
remove_selected_item: function() {
|
remove_selected_items: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
var selected_items = [];
|
var selected_items = [];
|
||||||
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
|
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
|
||||||
@ -487,6 +510,7 @@ erpnext.POS = Class.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.refresh_grid();
|
this.refresh_grid();
|
||||||
},
|
},
|
||||||
refresh_grid: function() {
|
refresh_grid: function() {
|
||||||
@ -494,6 +518,22 @@ erpnext.POS = Class.extend({
|
|||||||
this.frm.script_manager.trigger("calculate_taxes_and_totals");
|
this.frm.script_manager.trigger("calculate_taxes_and_totals");
|
||||||
this.refresh();
|
this.refresh();
|
||||||
},
|
},
|
||||||
|
selected_item_qty_operation: function(item_code, operation) {
|
||||||
|
var me = this;
|
||||||
|
var child = wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||||
|
this.frm.cscript.fname, this.frm.doctype);
|
||||||
|
|
||||||
|
$.each(child, function(i, d) {
|
||||||
|
if (d.item_code == item_code) {
|
||||||
|
if (operation == "increase-qty")
|
||||||
|
d.qty += 1;
|
||||||
|
else if (operation == "decrease-qty")
|
||||||
|
d.qty != 1 ? d.qty -= 1 : d.qty = 1;
|
||||||
|
|
||||||
|
me.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
make_payment: function() {
|
make_payment: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
|
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
|
||||||
|
@ -54,7 +54,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
"voucher_no": doc.name,
|
"voucher_no": doc.name,
|
||||||
"from_date": doc.posting_date,
|
"from_date": doc.posting_date,
|
||||||
"to_date": doc.posting_date,
|
"to_date": doc.posting_date,
|
||||||
"company": doc.company
|
"company": doc.company,
|
||||||
|
group_by_voucher: 0
|
||||||
};
|
};
|
||||||
wn.set_route("query-report", "General Ledger");
|
wn.set_route("query-report", "General Ledger");
|
||||||
}, "icon-table");
|
}, "icon-table");
|
||||||
|
@ -88,6 +88,7 @@ class DocType(SellingController):
|
|||||||
|
|
||||||
self.update_status_updater_args()
|
self.update_status_updater_args()
|
||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
||||||
|
|
||||||
# this sequence because outstanding may get -ve
|
# this sequence because outstanding may get -ve
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
@ -114,6 +115,7 @@ class DocType(SellingController):
|
|||||||
|
|
||||||
self.update_status_updater_args()
|
self.update_status_updater_args()
|
||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
||||||
|
|
||||||
self.make_cancel_gl_entries()
|
self.make_cancel_gl_entries()
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-05-24 19:29:05",
|
"creation": "2013-05-24 19:29:05",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 19:24:29",
|
"modified": "2014-01-16 15:36:16",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -1094,7 +1094,7 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Recurring Type",
|
"label": "Recurring Type",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
|
"options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
|
@ -565,16 +565,17 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
where against_invoice=%s""", si.doc.name))
|
where against_invoice=%s""", si.doc.name))
|
||||||
|
|
||||||
def test_recurring_invoice(self):
|
def test_recurring_invoice(self):
|
||||||
from webnotes.utils import now_datetime, get_first_day, get_last_day, add_to_date
|
from webnotes.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate
|
||||||
today = now_datetime().date()
|
from accounts.utils import get_fiscal_year
|
||||||
|
today = nowdate()
|
||||||
base_si = webnotes.bean(copy=test_records[0])
|
base_si = webnotes.bean(copy=test_records[0])
|
||||||
base_si.doc.fields.update({
|
base_si.doc.fields.update({
|
||||||
"convert_into_recurring_invoice": 1,
|
"convert_into_recurring_invoice": 1,
|
||||||
"recurring_type": "Monthly",
|
"recurring_type": "Monthly",
|
||||||
"notification_email_address": "test@example.com, test1@example.com, test2@example.com",
|
"notification_email_address": "test@example.com, test1@example.com, test2@example.com",
|
||||||
"repeat_on_day_of_month": today.day,
|
"repeat_on_day_of_month": getdate(today).day,
|
||||||
"posting_date": today,
|
"posting_date": today,
|
||||||
|
"fiscal_year": get_fiscal_year(today)[0],
|
||||||
"invoice_period_from_date": get_first_day(today),
|
"invoice_period_from_date": get_first_day(today),
|
||||||
"invoice_period_to_date": get_last_day(today)
|
"invoice_period_to_date": get_last_day(today)
|
||||||
})
|
})
|
||||||
|
@ -9,11 +9,13 @@ from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
columns = get_columns()
|
supplier_naming_by = webnotes.conn.get_value("Buying Settings", None, "supp_master_name")
|
||||||
|
columns = get_columns(supplier_naming_by)
|
||||||
entries = get_gl_entries(filters)
|
entries = get_gl_entries(filters)
|
||||||
account_supplier = dict(webnotes.conn.sql("""select account.name, supplier.supplier_name
|
account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select acc.name,
|
||||||
from `tabAccount` account, `tabSupplier` supplier
|
supp.supplier_name, supp.name as supplier
|
||||||
where account.master_type="Supplier" and supplier.name=account.master_name"""))
|
from `tabAccount` acc, `tabSupplier` supp
|
||||||
|
where acc.master_type="Supplier" and supp.name=acc.master_name""", as_dict=1)))
|
||||||
|
|
||||||
entries_after_report_date = [[gle.voucher_type, gle.voucher_no]
|
entries_after_report_date = [[gle.voucher_type, gle.voucher_no]
|
||||||
for gle in get_gl_entries(filters, before_report_date=False)]
|
for gle in get_gl_entries(filters, before_report_date=False)]
|
||||||
@ -37,9 +39,7 @@ def execute(filters=None):
|
|||||||
|
|
||||||
if abs(flt(outstanding_amount)) > 0.01:
|
if abs(flt(outstanding_amount)) > 0.01:
|
||||||
paid_amount = invoiced_amount - outstanding_amount
|
paid_amount = invoiced_amount - outstanding_amount
|
||||||
row = [gle.posting_date, gle.account, account_supplier.get(gle.account, ""),
|
row = [gle.posting_date, gle.account, gle.voucher_type, gle.voucher_no,
|
||||||
gle.voucher_type, gle.voucher_no, gle.remarks,
|
|
||||||
account_supplier_type_map.get(gle.account),
|
|
||||||
voucher_details.get("due_date", ""), voucher_details.get("bill_no", ""),
|
voucher_details.get("due_date", ""), voucher_details.get("bill_no", ""),
|
||||||
voucher_details.get("bill_date", ""), invoiced_amount,
|
voucher_details.get("bill_date", ""), invoiced_amount,
|
||||||
paid_amount, outstanding_amount]
|
paid_amount, outstanding_amount]
|
||||||
@ -50,21 +50,38 @@ def execute(filters=None):
|
|||||||
else:
|
else:
|
||||||
ageing_based_on_date = gle.posting_date
|
ageing_based_on_date = gle.posting_date
|
||||||
|
|
||||||
row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount)
|
row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount) + \
|
||||||
|
[account_map.get(gle.account).get("supplier") or ""]
|
||||||
|
|
||||||
|
if supplier_naming_by == "Naming Series":
|
||||||
|
row += [account_map.get(gle.account).get("supplier_name") or ""]
|
||||||
|
|
||||||
|
row += [account_supplier_type_map.get(gle.account), gle.remarks]
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
|
for i in range(0, len(data)):
|
||||||
|
data[i].insert(4, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
|
||||||
|
% ("/".join(["#Form", data[i][2], data[i][3]]),))
|
||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
def get_columns():
|
def get_columns(supplier_naming_by):
|
||||||
return [
|
columns = [
|
||||||
"Posting Date:Date:80", "Account:Link/Account:150", "Supplier::150", "Voucher Type::110",
|
"Posting Date:Date:80", "Account:Link/Account:150", "Voucher Type::110",
|
||||||
"Voucher No::120", "Remarks::150", "Supplier Type:Link/Supplier Type:120",
|
"Voucher No::120", "::30", "Due Date:Date:80", "Bill No::80", "Bill Date:Date:80",
|
||||||
"Due Date:Date:80", "Bill No::80", "Bill Date:Date:80",
|
|
||||||
"Invoiced Amount:Currency:100", "Paid Amount:Currency:100",
|
"Invoiced Amount:Currency:100", "Paid Amount:Currency:100",
|
||||||
"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100",
|
"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100",
|
||||||
"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100"
|
"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100",
|
||||||
|
"Supplier:Link/Supplier:150"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if supplier_naming_by == "Naming Series":
|
||||||
|
columns += ["Supplier Name::110"]
|
||||||
|
|
||||||
|
columns += ["Supplier Type:Link/Supplier Type:120", "Remarks::150"]
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
def get_gl_entries(filters, before_report_date=True):
|
def get_gl_entries(filters, before_report_date=True):
|
||||||
conditions, supplier_accounts = get_conditions(filters, before_report_date)
|
conditions, supplier_accounts = get_conditions(filters, before_report_date)
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
@ -101,8 +118,8 @@ def get_conditions(filters, before_report_date=True):
|
|||||||
|
|
||||||
def get_account_supplier_type_map():
|
def get_account_supplier_type_map():
|
||||||
account_supplier_type_map = {}
|
account_supplier_type_map = {}
|
||||||
for each in webnotes.conn.sql("""select t2.name, t1.supplier_type from `tabSupplier` t1,
|
for each in webnotes.conn.sql("""select acc.name, supp.supplier_type from `tabSupplier` supp,
|
||||||
`tabAccount` t2 where t1.name = t2.master_name group by t2.name"""):
|
`tabAccount` acc where supp.name = acc.master_name group by acc.name"""):
|
||||||
account_supplier_type_map[each[0]] = each[1]
|
account_supplier_type_map[each[0]] = each[1]
|
||||||
|
|
||||||
return account_supplier_type_map
|
return account_supplier_type_map
|
||||||
|
@ -15,26 +15,34 @@ class AccountsReceivableReport(object):
|
|||||||
else self.filters.report_date
|
else self.filters.report_date
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
return self.get_columns(), self.get_data()
|
customer_naming_by = webnotes.conn.get_value("Selling Settings", None, "cust_master_name")
|
||||||
|
return self.get_columns(customer_naming_by), self.get_data(customer_naming_by)
|
||||||
|
|
||||||
def get_columns(self):
|
def get_columns(self, customer_naming_by):
|
||||||
return [
|
columns = [
|
||||||
"Posting Date:Date:80", "Account:Link/Account:150",
|
"Posting Date:Date:80", "Account:Link/Account:150",
|
||||||
"Voucher Type::110", "Voucher No::120", "::30",
|
"Voucher Type::110", "Voucher No::120", "::30",
|
||||||
"Due Date:Date:80",
|
"Due Date:Date:80",
|
||||||
"Invoiced Amount:Currency:100", "Payment Received:Currency:100",
|
"Invoiced Amount:Currency:100", "Payment Received:Currency:100",
|
||||||
"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100",
|
"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100",
|
||||||
"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100",
|
"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100",
|
||||||
"Customer:Link/Customer:200", "Territory:Link/Territory:80", "Remarks::200"
|
"Customer:Link/Customer:200"
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_data(self):
|
if customer_naming_by == "Naming Series":
|
||||||
|
columns += ["Customer Name::110"]
|
||||||
|
|
||||||
|
columns += ["Territory:Link/Territory:80", "Remarks::200"]
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
def get_data(self, customer_naming_by):
|
||||||
data = []
|
data = []
|
||||||
future_vouchers = self.get_entries_after(self.filters.report_date)
|
future_vouchers = self.get_entries_after(self.filters.report_date)
|
||||||
for gle in self.get_entries_till(self.filters.report_date):
|
for gle in self.get_entries_till(self.filters.report_date):
|
||||||
if self.is_receivable(gle, future_vouchers):
|
if self.is_receivable(gle, future_vouchers):
|
||||||
outstanding_amount = self.get_outstanding_amount(gle, self.filters.report_date)
|
outstanding_amount = self.get_outstanding_amount(gle, self.filters.report_date)
|
||||||
if abs(outstanding_amount) > 0.01:
|
if abs(outstanding_amount) > 0.0:
|
||||||
due_date = self.get_due_date(gle)
|
due_date = self.get_due_date(gle)
|
||||||
invoiced_amount = gle.debit if (gle.debit > 0) else 0
|
invoiced_amount = gle.debit if (gle.debit > 0) else 0
|
||||||
payment_received = invoiced_amount - outstanding_amount
|
payment_received = invoiced_amount - outstanding_amount
|
||||||
@ -42,13 +50,18 @@ class AccountsReceivableReport(object):
|
|||||||
gle.voucher_type, gle.voucher_no, due_date,
|
gle.voucher_type, gle.voucher_no, due_date,
|
||||||
invoiced_amount, payment_received,
|
invoiced_amount, payment_received,
|
||||||
outstanding_amount]
|
outstanding_amount]
|
||||||
entry_date = due_date if self.filters.ageing_based_on=="Due Date" \
|
entry_date = due_date if self.filters.ageing_based_on == "Due Date" \
|
||||||
else gle.posting_date
|
else gle.posting_date
|
||||||
row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount)
|
row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) + \
|
||||||
row += [self.get_customer(gle.account), self.get_territory(gle.account), gle.remarks]
|
[self.get_customer(gle.account)]
|
||||||
|
|
||||||
|
if customer_naming_by == "Naming Series":
|
||||||
|
row += [self.get_customer_name(gle.account)]
|
||||||
|
|
||||||
|
row += [self.get_territory(gle.account), gle.remarks]
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
for i in range(0,len(data)):
|
for i in range(0, len(data)):
|
||||||
data[i].insert(4, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
|
data[i].insert(4, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
|
||||||
% ("/".join(["#Form", data[i][2], data[i][3]]),))
|
% ("/".join(["#Form", data[i][2], data[i][3]]),))
|
||||||
|
|
||||||
@ -65,8 +78,16 @@ class AccountsReceivableReport(object):
|
|||||||
if getdate(e.posting_date) <= report_date)
|
if getdate(e.posting_date) <= report_date)
|
||||||
|
|
||||||
def is_receivable(self, gle, future_vouchers):
|
def is_receivable(self, gle, future_vouchers):
|
||||||
return ((not gle.against_voucher) or (gle.against_voucher==gle.voucher_no) or
|
return (
|
||||||
((gle.against_voucher_type, gle.against_voucher) in future_vouchers))
|
# advance
|
||||||
|
(not gle.against_voucher) or
|
||||||
|
|
||||||
|
# sales invoice
|
||||||
|
(gle.against_voucher==gle.voucher_no and gle.debit > 0) or
|
||||||
|
|
||||||
|
# entries adjusted with future vouchers
|
||||||
|
((gle.against_voucher_type, gle.against_voucher) in future_vouchers)
|
||||||
|
)
|
||||||
|
|
||||||
def get_outstanding_amount(self, gle, report_date):
|
def get_outstanding_amount(self, gle, report_date):
|
||||||
payment_received = 0.0
|
payment_received = 0.0
|
||||||
@ -77,6 +98,9 @@ class AccountsReceivableReport(object):
|
|||||||
return flt(gle.debit) - flt(gle.credit) - payment_received
|
return flt(gle.debit) - flt(gle.credit) - payment_received
|
||||||
|
|
||||||
def get_customer(self, account):
|
def get_customer(self, account):
|
||||||
|
return self.get_account_map().get(account).get("customer") or ""
|
||||||
|
|
||||||
|
def get_customer_name(self, account):
|
||||||
return self.get_account_map().get(account).get("customer_name") or ""
|
return self.get_account_map().get(account).get("customer_name") or ""
|
||||||
|
|
||||||
def get_territory(self, account):
|
def get_territory(self, account):
|
||||||
@ -85,10 +109,10 @@ class AccountsReceivableReport(object):
|
|||||||
def get_account_map(self):
|
def get_account_map(self):
|
||||||
if not hasattr(self, "account_map"):
|
if not hasattr(self, "account_map"):
|
||||||
self.account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select
|
self.account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select
|
||||||
account.name, customer.name as customer_name, customer.territory
|
acc.name, cust.name as customer, cust.customer_name, cust.territory
|
||||||
from `tabAccount` account, `tabCustomer` customer
|
from `tabAccount` acc, `tabCustomer` cust
|
||||||
where account.master_type="Customer"
|
where acc.master_type="Customer"
|
||||||
and customer.name=account.master_name""", as_dict=True)))
|
and cust.name=acc.master_name""", as_dict=True)))
|
||||||
|
|
||||||
return self.account_map
|
return self.account_map
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ wn.query_reports["Bank Reconciliation Statement"] = {
|
|||||||
"label": wn._("Bank Account"),
|
"label": wn._("Bank Account"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
|
"reqd": 1,
|
||||||
"get_query": function() {
|
"get_query": function() {
|
||||||
return {
|
return {
|
||||||
"query": "accounts.utils.get_account_list",
|
"query": "accounts.utils.get_account_list",
|
||||||
@ -22,7 +23,8 @@ wn.query_reports["Bank Reconciliation Statement"] = {
|
|||||||
"fieldname":"report_date",
|
"fieldname":"report_date",
|
||||||
"label": wn._("Date"),
|
"label": wn._("Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"default": get_today()
|
"default": get_today(),
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -3,12 +3,13 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import _, msgprint
|
|
||||||
from webnotes.utils import flt
|
from webnotes.utils import flt
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
|
|
||||||
|
debit_or_credit = webnotes.conn.get_value("Account", filters["account"], "debit_or_credit")
|
||||||
|
|
||||||
columns = get_columns()
|
columns = get_columns()
|
||||||
data = get_entries(filters)
|
data = get_entries(filters)
|
||||||
|
|
||||||
@ -20,47 +21,39 @@ def execute(filters=None):
|
|||||||
total_debit += flt(d[4])
|
total_debit += flt(d[4])
|
||||||
total_credit += flt(d[5])
|
total_credit += flt(d[5])
|
||||||
|
|
||||||
if webnotes.conn.get_value("Account", filters["account"], "debit_or_credit") == 'Debit':
|
if debit_or_credit == 'Debit':
|
||||||
bank_bal = flt(balance_as_per_company) - flt(total_debit) + flt(total_credit)
|
bank_bal = flt(balance_as_per_company) - flt(total_debit) + flt(total_credit)
|
||||||
else:
|
else:
|
||||||
bank_bal = flt(balance_as_per_company) + flt(total_debit) - flt(total_credit)
|
bank_bal = flt(balance_as_per_company) + flt(total_debit) - flt(total_credit)
|
||||||
|
|
||||||
data += [
|
data += [
|
||||||
["", "", "", "Balance as per company books", balance_as_per_company, ""],
|
get_balance_row("Balance as per company books", balance_as_per_company, debit_or_credit),
|
||||||
["", "", "", "Amounts not reflected in bank", total_debit, total_credit],
|
["", "", "", "Amounts not reflected in bank", total_debit, total_credit],
|
||||||
["", "", "", "Balance as per bank", bank_bal, ""]
|
get_balance_row("Balance as per bank", bank_bal, debit_or_credit)
|
||||||
]
|
]
|
||||||
|
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
def get_columns():
|
def get_columns():
|
||||||
return ["Journal Voucher:Link/Journal Voucher:140", "Posting Date:Date:100",
|
return ["Journal Voucher:Link/Journal Voucher:140", "Posting Date:Date:100",
|
||||||
"Clearance Date:Date:110", "Against Account:Link/Account:200",
|
"Clearance Date:Date:110", "Against Account:Link/Account:200",
|
||||||
"Debit:Currency:120", "Credit:Currency:120"
|
"Debit:Currency:120", "Credit:Currency:120"
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_conditions(filters):
|
|
||||||
conditions = ""
|
|
||||||
if not filters.get("account"):
|
|
||||||
msgprint(_("Please select Bank Account"), raise_exception=1)
|
|
||||||
else:
|
|
||||||
conditions += " and jvd.account = %(account)s"
|
|
||||||
|
|
||||||
if not filters.get("report_date"):
|
|
||||||
msgprint(_("Please select Date on which you want to run the report"), raise_exception=1)
|
|
||||||
else:
|
|
||||||
conditions += """ and jv.posting_date <= %(report_date)s
|
|
||||||
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s"""
|
|
||||||
|
|
||||||
return conditions
|
|
||||||
|
|
||||||
def get_entries(filters):
|
def get_entries(filters):
|
||||||
conditions = get_conditions(filters)
|
entries = webnotes.conn.sql("""select
|
||||||
entries = webnotes.conn.sql("""select jv.name, jv.posting_date, jv.clearance_date,
|
jv.name, jv.posting_date, jv.clearance_date, jvd.against_account, jvd.debit, jvd.credit
|
||||||
jvd.against_account, jvd.debit, jvd.credit
|
from
|
||||||
from `tabJournal Voucher Detail` jvd, `tabJournal Voucher` jv
|
`tabJournal Voucher Detail` jvd, `tabJournal Voucher` jv
|
||||||
where jvd.parent = jv.name and jv.docstatus=1 and ifnull(jv.cheque_no, '')!= '' %s
|
where jvd.parent = jv.name and jv.docstatus=1 and ifnull(jv.cheque_no, '')!= ''
|
||||||
order by jv.name DESC""" % conditions, filters, as_list=1)
|
and jvd.account = %(account)s and jv.posting_date <= %(report_date)s
|
||||||
|
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s
|
||||||
|
order by jv.name DESC""", filters, as_list=1)
|
||||||
|
|
||||||
return entries
|
return entries
|
||||||
|
|
||||||
|
def get_balance_row(label, amount, debit_or_credit):
|
||||||
|
if debit_or_credit == "Debit":
|
||||||
|
return ["", "", "", label, amount, 0]
|
||||||
|
else:
|
||||||
|
return ["", "", "", label, 0, amount]
|
||||||
|
@ -73,6 +73,11 @@ def get_conditions(filters):
|
|||||||
if filters.get("voucher_no"):
|
if filters.get("voucher_no"):
|
||||||
conditions.append("voucher_no=%(voucher_no)s")
|
conditions.append("voucher_no=%(voucher_no)s")
|
||||||
|
|
||||||
|
|
||||||
|
from webnotes.widgets.reportview import build_match_conditions
|
||||||
|
match_conditions = build_match_conditions("GL Entry")
|
||||||
|
if match_conditions: conditions.append(match_conditions)
|
||||||
|
|
||||||
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
||||||
|
|
||||||
def get_data_with_opening_closing(filters, account_details, gl_entries):
|
def get_data_with_opening_closing(filters, account_details, gl_entries):
|
||||||
@ -136,7 +141,7 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
|
|||||||
or cstr(gle.is_advance) == "Yes"):
|
or cstr(gle.is_advance) == "Yes"):
|
||||||
gle_map[gle.account].opening += amount
|
gle_map[gle.account].opening += amount
|
||||||
opening += amount
|
opening += amount
|
||||||
elif gle.posting_date < filters.to_date:
|
elif gle.posting_date <= filters.to_date:
|
||||||
gle_map[gle.account].entries.append(gle)
|
gle_map[gle.account].entries.append(gle)
|
||||||
gle_map[gle.account].total_debit += flt(gle.debit)
|
gle_map[gle.account].total_debit += flt(gle.debit)
|
||||||
gle_map[gle.account].total_credit += flt(gle.credit)
|
gle_map[gle.account].total_credit += flt(gle.credit)
|
||||||
|
@ -12,7 +12,8 @@ def execute(filters=None):
|
|||||||
|
|
||||||
item_list = get_items(filters)
|
item_list = get_items(filters)
|
||||||
aii_account_map = get_aii_accounts()
|
aii_account_map = get_aii_accounts()
|
||||||
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
if item_list:
|
||||||
|
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for d in item_list:
|
for d in item_list:
|
||||||
|
@ -11,7 +11,8 @@ def execute(filters=None):
|
|||||||
last_col = len(columns)
|
last_col = len(columns)
|
||||||
|
|
||||||
item_list = get_items(filters)
|
item_list = get_items(filters)
|
||||||
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
if item_list:
|
||||||
|
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for d in item_list:
|
for d in item_list:
|
||||||
@ -39,7 +40,6 @@ def get_columns():
|
|||||||
"Qty:Float:120", "Rate:Currency:120", "Amount:Currency:120"
|
"Qty:Float:120", "Rate:Currency:120", "Amount:Currency:120"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_conditions(filters):
|
def get_conditions(filters):
|
||||||
conditions = ""
|
conditions = ""
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes.utils import nowdate, nowtime, cstr, flt, now, getdate, add_months
|
from webnotes.utils import nowdate, cstr, flt, now, getdate, add_months
|
||||||
from webnotes.model.doc import addchild
|
from webnotes.model.doc import addchild
|
||||||
from webnotes import msgprint, _
|
from webnotes import msgprint, _
|
||||||
from webnotes.utils import formatdate
|
from webnotes.utils import formatdate
|
||||||
@ -31,6 +31,8 @@ def get_fiscal_years(date=None, fiscal_year=None, label="Date", verbose=1):
|
|||||||
|
|
||||||
if not fy:
|
if not fy:
|
||||||
error_msg = """%s %s not in any Fiscal Year""" % (label, formatdate(date))
|
error_msg = """%s %s not in any Fiscal Year""" % (label, formatdate(date))
|
||||||
|
error_msg = """{msg}: {date}""".format(msg=_("Fiscal Year does not exist for date"),
|
||||||
|
date=formatdate(date))
|
||||||
if verbose: webnotes.msgprint(error_msg)
|
if verbose: webnotes.msgprint(error_msg)
|
||||||
raise FiscalYearError, error_msg
|
raise FiscalYearError, error_msg
|
||||||
|
|
||||||
@ -62,7 +64,6 @@ def get_balance_on(account=None, date=None):
|
|||||||
try:
|
try:
|
||||||
year_start_date = get_fiscal_year(date, verbose=0)[1]
|
year_start_date = get_fiscal_year(date, verbose=0)[1]
|
||||||
except FiscalYearError, e:
|
except FiscalYearError, e:
|
||||||
from webnotes.utils import getdate
|
|
||||||
if getdate(date) > getdate(nowdate()):
|
if getdate(date) > getdate(nowdate()):
|
||||||
# if fiscal year not found and the date is greater than today
|
# if fiscal year not found and the date is greater than today
|
||||||
# get fiscal year for today's date and its corresponding year start date
|
# get fiscal year for today's date and its corresponding year start date
|
||||||
@ -220,17 +221,26 @@ def get_cost_center_list(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
|
tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
|
||||||
|
|
||||||
def remove_against_link_from_jv(ref_type, ref_no, against_field):
|
def remove_against_link_from_jv(ref_type, ref_no, against_field):
|
||||||
webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null,
|
linked_jv = webnotes.conn.sql_list("""select parent from `tabJournal Voucher Detail`
|
||||||
modified=%s, modified_by=%s
|
where `%s`=%s and docstatus < 2""" % (against_field, "%s"), (ref_no))
|
||||||
where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
|
|
||||||
(now(), webnotes.session.user, ref_no))
|
if linked_jv:
|
||||||
|
webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null,
|
||||||
|
modified=%s, modified_by=%s
|
||||||
|
where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
|
||||||
|
(now(), webnotes.session.user, ref_no))
|
||||||
|
|
||||||
|
webnotes.conn.sql("""update `tabGL Entry`
|
||||||
|
set against_voucher_type=null, against_voucher=null,
|
||||||
|
modified=%s, modified_by=%s
|
||||||
|
where against_voucher_type=%s and against_voucher=%s
|
||||||
|
and voucher_no != ifnull(against_voucher, '')""",
|
||||||
|
(now(), webnotes.session.user, ref_type, ref_no))
|
||||||
|
|
||||||
|
webnotes.msgprint("{msg} {linked_jv}".format(msg = _("""Following linked Journal Vouchers \
|
||||||
|
made against this transaction has been unlinked. You can link them again with other \
|
||||||
|
transactions via Payment Reconciliation Tool."""), linked_jv="\n".join(linked_jv)))
|
||||||
|
|
||||||
webnotes.conn.sql("""update `tabGL Entry`
|
|
||||||
set against_voucher_type=null, against_voucher=null,
|
|
||||||
modified=%s, modified_by=%s
|
|
||||||
where against_voucher_type=%s and against_voucher=%s
|
|
||||||
and voucher_no != ifnull(against_voucher, '')""",
|
|
||||||
(now(), webnotes.session.user, ref_type, ref_no))
|
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def get_company_default(company, fieldname):
|
def get_company_default(company, fieldname):
|
||||||
|
@ -22,7 +22,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
if(this.frm.fields_dict.buying_price_list) {
|
if(this.frm.fields_dict.buying_price_list) {
|
||||||
this.frm.set_query("buying_price_list", function() {
|
this.frm.set_query("buying_price_list", function() {
|
||||||
return{
|
return{
|
||||||
filters: { 'buying_or_selling': "Buying" }
|
filters: { 'buying': 1 }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -302,11 +302,11 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
|
|
||||||
calculate_totals: function() {
|
calculate_totals: function() {
|
||||||
var tax_count = this.frm.tax_doclist.length;
|
var tax_count = this.frm.tax_doclist.length;
|
||||||
this.frm.doc.grand_total = flt(
|
this.frm.doc.grand_total = flt(tax_count ?
|
||||||
tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total,
|
this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total,
|
||||||
precision("grand_total"));
|
precision("grand_total"));
|
||||||
this.frm.doc.grand_total_import = flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate,
|
this.frm.doc.grand_total_import = flt(this.frm.doc.grand_total /
|
||||||
precision("grand_total_import"));
|
this.frm.doc.conversion_rate, precision("grand_total_import"));
|
||||||
|
|
||||||
this.frm.doc.total_tax = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
|
this.frm.doc.total_tax = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
|
||||||
precision("total_tax"));
|
precision("total_tax"));
|
||||||
@ -321,20 +321,26 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// other charges added/deducted
|
// other charges added/deducted
|
||||||
|
this.frm.doc.other_charges_added = 0.0
|
||||||
|
this.frm.doc.other_charges_deducted = 0.0
|
||||||
if(tax_count) {
|
if(tax_count) {
|
||||||
this.frm.doc.other_charges_added = wn.utils.sum($.map(this.frm.tax_doclist,
|
this.frm.doc.other_charges_added = wn.utils.sum($.map(this.frm.tax_doclist,
|
||||||
function(tax) { return (tax.add_deduct_tax == "Add" && in_list(["Valuation and Total", "Total"], tax.category)) ? tax.tax_amount : 0.0; }));
|
function(tax) { return (tax.add_deduct_tax == "Add"
|
||||||
|
&& in_list(["Valuation and Total", "Total"], tax.category)) ?
|
||||||
|
tax.tax_amount : 0.0; }));
|
||||||
|
|
||||||
this.frm.doc.other_charges_deducted = wn.utils.sum($.map(this.frm.tax_doclist,
|
this.frm.doc.other_charges_deducted = wn.utils.sum($.map(this.frm.tax_doclist,
|
||||||
function(tax) { return (tax.add_deduct_tax == "Deduct" && in_list(["Valuation and Total", "Total"], tax.category)) ? tax.tax_amount : 0.0; }));
|
function(tax) { return (tax.add_deduct_tax == "Deduct"
|
||||||
|
&& in_list(["Valuation and Total", "Total"], tax.category)) ?
|
||||||
|
tax.tax_amount : 0.0; }));
|
||||||
|
|
||||||
wn.model.round_floats_in(this.frm.doc, ["other_charges_added", "other_charges_deducted"]);
|
wn.model.round_floats_in(this.frm.doc,
|
||||||
|
["other_charges_added", "other_charges_deducted"]);
|
||||||
this.frm.doc.other_charges_added_import = flt(this.frm.doc.other_charges_added / this.frm.doc.conversion_rate,
|
|
||||||
precision("other_charges_added_import"));
|
|
||||||
this.frm.doc.other_charges_deducted_import = flt(this.frm.doc.other_charges_deducted / this.frm.doc.conversion_rate,
|
|
||||||
precision("other_charges_deducted_import"));
|
|
||||||
}
|
}
|
||||||
|
this.frm.doc.other_charges_added_import = flt(this.frm.doc.other_charges_added /
|
||||||
|
this.frm.doc.conversion_rate, precision("other_charges_added_import"));
|
||||||
|
this.frm.doc.other_charges_deducted_import = flt(this.frm.doc.other_charges_deducted /
|
||||||
|
this.frm.doc.conversion_rate, precision("other_charges_deducted_import"));
|
||||||
},
|
},
|
||||||
|
|
||||||
_cleanup: function() {
|
_cleanup: function() {
|
||||||
|
@ -22,7 +22,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
pr = make_purchase_receipt(po.doc.name)
|
pr = make_purchase_receipt(po.doc.name)
|
||||||
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
|
||||||
|
pr[0]["posting_date"] = "2013-05-12"
|
||||||
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
||||||
self.assertEquals(len(pr), len(test_records[0]))
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
|
||||||
self.assertEquals(len(pr), len(test_records[0]))
|
self.assertEquals(len(pr), len(test_records[0]))
|
||||||
|
pr[0]["posting_date"] = "2013-05-12"
|
||||||
pr[0].naming_series = "_T-Purchase Receipt-"
|
pr[0].naming_series = "_T-Purchase Receipt-"
|
||||||
pr[1].qty = 4.0
|
pr[1].qty = 4.0
|
||||||
pr_bean = webnotes.bean(pr)
|
pr_bean = webnotes.bean(pr)
|
||||||
@ -66,6 +66,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
pr1 = make_purchase_receipt(po.doc.name)
|
pr1 = make_purchase_receipt(po.doc.name)
|
||||||
pr1[0].naming_series = "_T-Purchase Receipt-"
|
pr1[0].naming_series = "_T-Purchase Receipt-"
|
||||||
|
pr1[0]["posting_date"] = "2013-05-12"
|
||||||
pr1[1].qty = 8
|
pr1[1].qty = 8
|
||||||
pr1_bean = webnotes.bean(pr1)
|
pr1_bean = webnotes.bean(pr1)
|
||||||
pr1_bean.insert()
|
pr1_bean.insert()
|
||||||
@ -88,7 +89,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
|
self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
|
||||||
self.assertEquals(len(pi), len(test_records[0]))
|
self.assertEquals(len(pi), len(test_records[0]))
|
||||||
|
pi[0]["posting_date"] = "2013-05-12"
|
||||||
pi[0].bill_no = "NA"
|
pi[0].bill_no = "NA"
|
||||||
webnotes.bean(pi).insert()
|
webnotes.bean(pi).insert()
|
||||||
|
|
||||||
|
@ -95,6 +95,6 @@ cur_frm.cscript.make_contact = function() {
|
|||||||
|
|
||||||
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) {
|
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) {
|
||||||
return{
|
return{
|
||||||
filters:{'buying_or_selling': "Buying"}
|
filters:{'buying': 1}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import msgprint, _
|
from webnotes import msgprint, _, throw
|
||||||
from webnotes.utils import getdate, flt, add_days, cstr
|
from webnotes.utils import getdate, flt, add_days, cstr
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ def _get_price_list_rate(args, item_bean, meta):
|
|||||||
# try fetching from price list
|
# try fetching from price list
|
||||||
if args.buying_price_list and args.price_list_currency:
|
if args.buying_price_list and args.price_list_currency:
|
||||||
price_list_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
price_list_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||||
where price_list=%s and item_code=%s and buying_or_selling='Buying'""",
|
where price_list=%s and item_code=%s and buying=1""",
|
||||||
(args.buying_price_list, args.item_code), as_dict=1)
|
(args.buying_price_list, args.item_code), as_dict=1)
|
||||||
|
|
||||||
if price_list_rate:
|
if price_list_rate:
|
||||||
@ -122,14 +122,12 @@ def _validate_item_details(args, item):
|
|||||||
|
|
||||||
# validate if purchase item or subcontracted item
|
# validate if purchase item or subcontracted item
|
||||||
if item.is_purchase_item != "Yes":
|
if item.is_purchase_item != "Yes":
|
||||||
msgprint(_("Item") + (" %s: " % item.name) + _("not a purchase item"),
|
throw(_("Item") + (" %s: " % item.name) + _("not a purchase item"))
|
||||||
raise_exception=True)
|
|
||||||
|
|
||||||
if args.is_subcontracted == "Yes" and item.is_sub_contracted_item != "Yes":
|
if args.is_subcontracted == "Yes" and item.is_sub_contracted_item != "Yes":
|
||||||
msgprint(_("Item") + (" %s: " % item.name) +
|
throw(_("Item") + (" %s: " % item.name) +
|
||||||
_("not a sub-contracted item.") +
|
_("not a sub-contracted item.") +
|
||||||
_("Please select a sub-contracted item or do not sub-contract the transaction."),
|
_("Please select a sub-contracted item or do not sub-contract the transaction."))
|
||||||
raise_exception=True)
|
|
||||||
|
|
||||||
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
|
||||||
"""returns last purchase details in stock uom"""
|
"""returns last purchase details in stock uom"""
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import _, msgprint
|
from webnotes import _, throw
|
||||||
from webnotes.utils import flt, cint, today, cstr
|
from webnotes.utils import flt, cint, today, cstr
|
||||||
from webnotes.model.code import get_obj
|
from webnotes.model.code import get_obj
|
||||||
from erpnext.setup.utils import get_company_currency
|
from erpnext.setup.utils import get_company_currency
|
||||||
@ -44,14 +44,13 @@ class AccountsController(TransactionBase):
|
|||||||
def validate_for_freezed_account(self):
|
def validate_for_freezed_account(self):
|
||||||
for fieldname in ["customer", "supplier"]:
|
for fieldname in ["customer", "supplier"]:
|
||||||
if self.meta.get_field(fieldname) and self.doc.fields.get(fieldname):
|
if self.meta.get_field(fieldname) and self.doc.fields.get(fieldname):
|
||||||
accounts = webnotes.conn.get_values("Account", {"master_type": fieldname.title(),
|
accounts = webnotes.conn.get_values("Account",
|
||||||
"master_name": self.doc.fields[fieldname], "company": self.doc.company},
|
{"master_type": fieldname.title(), "master_name": self.doc.fields[fieldname],
|
||||||
"freeze_account", as_dict=1)
|
"company": self.doc.company}, "name")
|
||||||
|
|
||||||
if accounts:
|
if accounts:
|
||||||
if not filter(lambda x: cstr(x.freeze_account) in ["", "No"], accounts):
|
from accounts.doctype.gl_entry.gl_entry import validate_frozen_account
|
||||||
msgprint(_("Account for this ") + fieldname + _(" has been freezed. ") +
|
for account in accounts:
|
||||||
self.doc.doctype + _(" can not be made."), raise_exception=1)
|
validate_frozen_account(account[0])
|
||||||
|
|
||||||
def set_price_list_currency(self, buying_or_selling):
|
def set_price_list_currency(self, buying_or_selling):
|
||||||
if self.meta.get_field("currency"):
|
if self.meta.get_field("currency"):
|
||||||
@ -179,17 +178,17 @@ class AccountsController(TransactionBase):
|
|||||||
"""
|
"""
|
||||||
if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \
|
if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \
|
||||||
(not tax.row_id or cint(tax.row_id) >= tax.idx):
|
(not tax.row_id or cint(tax.row_id) >= tax.idx):
|
||||||
msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
|
throw((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
|
||||||
_("Please specify a valid") + " %(row_id_label)s") % {
|
_("Please specify a valid") + " %(row_id_label)s") % {
|
||||||
"idx": tax.idx,
|
"idx": tax.idx,
|
||||||
"taxes_doctype": tax.doctype,
|
"taxes_doctype": tax.doctype,
|
||||||
"row_id_label": self.meta.get_label("row_id",
|
"row_id_label": self.meta.get_label("row_id",
|
||||||
parentfield=self.other_fname)
|
parentfield=self.other_fname)
|
||||||
}, raise_exception=True)
|
})
|
||||||
|
|
||||||
def validate_inclusive_tax(self, tax):
|
def validate_inclusive_tax(self, tax):
|
||||||
def _on_previous_row_error(row_range):
|
def _on_previous_row_error(row_range):
|
||||||
msgprint((_("Row") + " # %(idx)s [%(doctype)s]: " +
|
throw((_("Row") + " # %(idx)s [%(doctype)s]: " +
|
||||||
_("to be included in Item's rate, it is required that: ") +
|
_("to be included in Item's rate, it is required that: ") +
|
||||||
" [" + _("Row") + " # %(row_range)s] " + _("also be included in Item's rate")) % {
|
" [" + _("Row") + " # %(row_range)s] " + _("also be included in Item's rate")) % {
|
||||||
"idx": tax.idx,
|
"idx": tax.idx,
|
||||||
@ -200,12 +199,12 @@ class AccountsController(TransactionBase):
|
|||||||
parentfield=self.other_fname),
|
parentfield=self.other_fname),
|
||||||
"charge_type": tax.charge_type,
|
"charge_type": tax.charge_type,
|
||||||
"row_range": row_range
|
"row_range": row_range
|
||||||
}, raise_exception=True)
|
})
|
||||||
|
|
||||||
if cint(tax.included_in_print_rate):
|
if cint(tax.included_in_print_rate):
|
||||||
if tax.charge_type == "Actual":
|
if tax.charge_type == "Actual":
|
||||||
# inclusive tax cannot be of type Actual
|
# inclusive tax cannot be of type Actual
|
||||||
msgprint((_("Row")
|
throw((_("Row")
|
||||||
+ " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" "
|
+ " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" "
|
||||||
+ "cannot be included in Item's rate") % {
|
+ "cannot be included in Item's rate") % {
|
||||||
"idx": tax.idx,
|
"idx": tax.idx,
|
||||||
@ -213,7 +212,7 @@ class AccountsController(TransactionBase):
|
|||||||
"charge_type_label": self.meta.get_label("charge_type",
|
"charge_type_label": self.meta.get_label("charge_type",
|
||||||
parentfield=self.other_fname),
|
parentfield=self.other_fname),
|
||||||
"charge_type": tax.charge_type,
|
"charge_type": tax.charge_type,
|
||||||
}, raise_exception=True)
|
})
|
||||||
elif tax.charge_type == "On Previous Row Amount" and \
|
elif tax.charge_type == "On Previous Row Amount" and \
|
||||||
not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate):
|
not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate):
|
||||||
# referred row should also be inclusive
|
# referred row should also be inclusive
|
||||||
@ -224,23 +223,22 @@ class AccountsController(TransactionBase):
|
|||||||
_on_previous_row_error("1 - %d" % (tax.row_id,))
|
_on_previous_row_error("1 - %d" % (tax.row_id,))
|
||||||
|
|
||||||
def calculate_taxes(self):
|
def calculate_taxes(self):
|
||||||
for item in self.item_doclist:
|
# maintain actual tax rate based on idx
|
||||||
|
actual_tax_dict = dict([[tax.idx, tax.rate] for tax in self.tax_doclist
|
||||||
|
if tax.charge_type == "Actual"])
|
||||||
|
|
||||||
|
for n, item in enumerate(self.item_doclist):
|
||||||
item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
|
item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
|
||||||
|
|
||||||
for i, tax in enumerate(self.tax_doclist):
|
for i, tax in enumerate(self.tax_doclist):
|
||||||
# tax_amount represents the amount of tax for the current step
|
# tax_amount represents the amount of tax for the current step
|
||||||
current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)
|
current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)
|
||||||
|
|
||||||
if hasattr(self, "set_item_tax_amount"):
|
# Adjust divisional loss to the last item
|
||||||
self.set_item_tax_amount(item, tax, current_tax_amount)
|
if tax.charge_type == "Actual":
|
||||||
|
actual_tax_dict[tax.idx] -= current_tax_amount
|
||||||
# case when net total is 0 but there is an actual type charge
|
if n == len(self.item_doclist) - 1:
|
||||||
# in this case add the actual amount to tax.tax_amount
|
current_tax_amount += actual_tax_dict[tax.idx]
|
||||||
# and tax.grand_total_for_current_item for the first such iteration
|
|
||||||
if tax.charge_type=="Actual" and \
|
|
||||||
not (current_tax_amount or self.doc.net_total or tax.tax_amount):
|
|
||||||
zero_net_total_adjustment = flt(tax.rate, self.precision("tax_amount", tax))
|
|
||||||
current_tax_amount += zero_net_total_adjustment
|
|
||||||
|
|
||||||
# store tax_amount for current item as it will be used for
|
# store tax_amount for current item as it will be used for
|
||||||
# charge type = 'On Previous Row Amount'
|
# charge type = 'On Previous Row Amount'
|
||||||
@ -252,7 +250,8 @@ class AccountsController(TransactionBase):
|
|||||||
if tax.category:
|
if tax.category:
|
||||||
# if just for valuation, do not add the tax amount in total
|
# if just for valuation, do not add the tax amount in total
|
||||||
# hence, setting it as 0 for further steps
|
# hence, setting it as 0 for further steps
|
||||||
current_tax_amount = 0.0 if (tax.category == "Valuation") else current_tax_amount
|
current_tax_amount = 0.0 if (tax.category == "Valuation") \
|
||||||
|
else current_tax_amount
|
||||||
|
|
||||||
current_tax_amount *= -1.0 if (tax.add_deduct_tax == "Deduct") else 1.0
|
current_tax_amount *= -1.0 if (tax.add_deduct_tax == "Deduct") else 1.0
|
||||||
|
|
||||||
@ -271,6 +270,11 @@ class AccountsController(TransactionBase):
|
|||||||
# in tax.total, accumulate grand total of each item
|
# in tax.total, accumulate grand total of each item
|
||||||
tax.total += tax.grand_total_for_current_item
|
tax.total += tax.grand_total_for_current_item
|
||||||
|
|
||||||
|
# set precision in the last item iteration
|
||||||
|
if n == len(self.item_doclist) - 1:
|
||||||
|
tax.total = flt(tax.total, self.precision("total", tax))
|
||||||
|
tax.tax_amount = flt(tax.tax_amount, self.precision("tax_amount", tax))
|
||||||
|
|
||||||
def get_current_tax_amount(self, item, tax, item_tax_map):
|
def get_current_tax_amount(self, item, tax, item_tax_map):
|
||||||
tax_rate = self._get_tax_rate(tax, item_tax_map)
|
tax_rate = self._get_tax_rate(tax, item_tax_map)
|
||||||
current_tax_amount = 0.0
|
current_tax_amount = 0.0
|
||||||
@ -384,23 +388,44 @@ class AccountsController(TransactionBase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
||||||
|
from controllers.status_updater import get_tolerance_for
|
||||||
|
item_tolerance = {}
|
||||||
|
global_tolerance = None
|
||||||
|
|
||||||
for item in self.doclist.get({"parentfield": "entries"}):
|
for item in self.doclist.get({"parentfield": "entries"}):
|
||||||
if item.fields.get(item_ref_dn):
|
if item.fields.get(item_ref_dn):
|
||||||
already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s`
|
ref_amt = flt(webnotes.conn.get_value(ref_dt + " Item",
|
||||||
where %s=%s and docstatus=1""" % (based_on, self.tname, item_ref_dn, '%s'),
|
|
||||||
item.fields[item_ref_dn])[0][0]
|
|
||||||
|
|
||||||
max_allowed_amt = flt(webnotes.conn.get_value(ref_dt + " Item",
|
|
||||||
item.fields[item_ref_dn], based_on), self.precision(based_on, item))
|
item.fields[item_ref_dn], based_on), self.precision(based_on, item))
|
||||||
|
if not ref_amt:
|
||||||
|
webnotes.msgprint(_("As amount for item") + ": " + item.item_code + _(" in ") +
|
||||||
|
ref_dt + _(" is zero, system will not check for over-billed"))
|
||||||
|
else:
|
||||||
|
already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s`
|
||||||
|
where %s=%s and docstatus=1 and parent != %s""" %
|
||||||
|
(based_on, self.tname, item_ref_dn, '%s', '%s'),
|
||||||
|
(item.fields[item_ref_dn], self.doc.name))[0][0]
|
||||||
|
|
||||||
total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]),
|
total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]),
|
||||||
self.precision(based_on, item))
|
self.precision(based_on, item))
|
||||||
|
|
||||||
if max_allowed_amt and total_billed_amt - max_allowed_amt > 0.02:
|
tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code,
|
||||||
webnotes.msgprint(_("Row ")+ cstr(item.idx) + ": " + cstr(item.item_code) +
|
item_tolerance, global_tolerance)
|
||||||
_(" will be over-billed against mentioned ") + cstr(ref_dt) +
|
|
||||||
_(". Max allowed " + cstr(based_on) + ": " + cstr(max_allowed_amt)),
|
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
|
||||||
raise_exception=1)
|
|
||||||
|
if total_billed_amt - max_allowed_amt > 0.01:
|
||||||
|
reduce_by = total_billed_amt - max_allowed_amt
|
||||||
|
|
||||||
|
webnotes.throw(_("Row #") + cstr(item.idx) + ": " +
|
||||||
|
_(" Max amount allowed for Item ") + cstr(item.item_code) +
|
||||||
|
_(" against ") + ref_dt + " " +
|
||||||
|
cstr(item.fields[ref_dt.lower().replace(" ", "_")]) + _(" is ") +
|
||||||
|
cstr(max_allowed_amt) + ". \n" +
|
||||||
|
_("""If you want to increase your overflow tolerance, please increase \
|
||||||
|
tolerance % in Global Defaults or Item master.
|
||||||
|
Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" +
|
||||||
|
_("""Also, please check if the order item has already been billed \
|
||||||
|
in the Sales Order"""))
|
||||||
|
|
||||||
def get_company_default(self, fieldname):
|
def get_company_default(self, fieldname):
|
||||||
from erpnext.accounts.utils import get_company_default
|
from erpnext.accounts.utils import get_company_default
|
||||||
|
@ -122,8 +122,8 @@ class BuyingController(StockController):
|
|||||||
self.round_floats_in(self.doc, ["net_total", "net_total_import"])
|
self.round_floats_in(self.doc, ["net_total", "net_total_import"])
|
||||||
|
|
||||||
def calculate_totals(self):
|
def calculate_totals(self):
|
||||||
self.doc.grand_total = flt(self.tax_doclist and \
|
self.doc.grand_total = flt(self.tax_doclist[-1].total if self.tax_doclist
|
||||||
self.tax_doclist[-1].total or self.doc.net_total, self.precision("grand_total"))
|
else self.doc.net_total, self.precision("grand_total"))
|
||||||
self.doc.grand_total_import = flt(self.doc.grand_total / self.doc.conversion_rate,
|
self.doc.grand_total_import = flt(self.doc.grand_total / self.doc.conversion_rate,
|
||||||
self.precision("grand_total_import"))
|
self.precision("grand_total_import"))
|
||||||
|
|
||||||
@ -136,6 +136,24 @@ class BuyingController(StockController):
|
|||||||
if self.meta.get_field("rounded_total_import"):
|
if self.meta.get_field("rounded_total_import"):
|
||||||
self.doc.rounded_total_import = _round(self.doc.grand_total_import)
|
self.doc.rounded_total_import = _round(self.doc.grand_total_import)
|
||||||
|
|
||||||
|
if self.meta.get_field("other_charges_added"):
|
||||||
|
self.doc.other_charges_added = flt(sum([flt(d.tax_amount) for d in self.tax_doclist
|
||||||
|
if d.add_deduct_tax=="Add" and d.category in ["Valuation and Total", "Total"]]),
|
||||||
|
self.precision("other_charges_added"))
|
||||||
|
|
||||||
|
if self.meta.get_field("other_charges_deducted"):
|
||||||
|
self.doc.other_charges_deducted = flt(sum([flt(d.tax_amount) for d in self.tax_doclist
|
||||||
|
if d.add_deduct_tax=="Deduct" and d.category in ["Valuation and Total", "Total"]]),
|
||||||
|
self.precision("other_charges_deducted"))
|
||||||
|
|
||||||
|
if self.meta.get_field("other_charges_added_import"):
|
||||||
|
self.doc.other_charges_added_import = flt(self.doc.other_charges_added /
|
||||||
|
self.doc.conversion_rate, self.precision("other_charges_added_import"))
|
||||||
|
|
||||||
|
if self.meta.get_field("other_charges_deducted_import"):
|
||||||
|
self.doc.other_charges_deducted_import = flt(self.doc.other_charges_deducted /
|
||||||
|
self.doc.conversion_rate, self.precision("other_charges_deducted_import"))
|
||||||
|
|
||||||
def calculate_outstanding_amount(self):
|
def calculate_outstanding_amount(self):
|
||||||
if self.doc.doctype == "Purchase Invoice" and self.doc.docstatus < 2:
|
if self.doc.doctype == "Purchase Invoice" and self.doc.docstatus < 2:
|
||||||
self.doc.total_advance = flt(self.doc.total_advance,
|
self.doc.total_advance = flt(self.doc.total_advance,
|
||||||
@ -162,29 +180,48 @@ class BuyingController(StockController):
|
|||||||
for item in self.item_doclist:
|
for item in self.item_doclist:
|
||||||
del item.fields["item_tax_amount"]
|
del item.fields["item_tax_amount"]
|
||||||
|
|
||||||
def set_item_tax_amount(self, item, tax, current_tax_amount):
|
# update valuation rate
|
||||||
|
def update_valuation_rate(self, parentfield):
|
||||||
"""
|
"""
|
||||||
item_tax_amount is the total tax amount applied on that item
|
item_tax_amount is the total tax amount applied on that item
|
||||||
stored for valuation
|
stored for valuation
|
||||||
|
|
||||||
TODO: rename item_tax_amount to valuation_tax_amount
|
TODO: rename item_tax_amount to valuation_tax_amount
|
||||||
"""
|
"""
|
||||||
if tax.category in ["Valuation", "Valuation and Total"] and \
|
stock_items = self.get_stock_items()
|
||||||
self.meta.get_field("item_tax_amount", parentfield=self.fname):
|
|
||||||
item.item_tax_amount += flt(current_tax_amount, self.precision("item_tax_amount", item))
|
|
||||||
|
|
||||||
# update valuation rate
|
stock_items_qty, stock_items_amount = 0, 0
|
||||||
def update_valuation_rate(self, parentfield):
|
last_stock_item_idx = 1
|
||||||
for item in self.doclist.get({"parentfield": parentfield}):
|
for d in self.doclist.get({"parentfield": parentfield}):
|
||||||
item.conversion_factor = item.conversion_factor or flt(webnotes.conn.get_value(
|
if d.item_code and d.item_code in stock_items:
|
||||||
"UOM Conversion Detail", {"parent": item.item_code, "uom": item.uom},
|
stock_items_qty += flt(d.qty)
|
||||||
"conversion_factor")) or 1
|
stock_items_amount += flt(d.amount)
|
||||||
|
last_stock_item_idx = d.idx
|
||||||
|
|
||||||
|
total_valuation_amount = sum([flt(d.tax_amount) for d in
|
||||||
|
self.doclist.get({"parentfield": "purchase_tax_details"})
|
||||||
|
if d.category in ["Valuation", "Valuation and Total"]])
|
||||||
|
|
||||||
|
|
||||||
|
valuation_amount_adjustment = total_valuation_amount
|
||||||
|
for i, item in enumerate(self.doclist.get({"parentfield": parentfield})):
|
||||||
|
if item.item_code and item.qty and item.item_code in stock_items:
|
||||||
|
item_proportion = flt(item.amount) / stock_items_amount if stock_items_amount \
|
||||||
|
else flt(item.qty) / stock_items_qty
|
||||||
|
|
||||||
|
if i == (last_stock_item_idx - 1):
|
||||||
|
item.item_tax_amount = flt(valuation_amount_adjustment,
|
||||||
|
self.precision("item_tax_amount", item))
|
||||||
|
else:
|
||||||
|
item.item_tax_amount = flt(item_proportion * total_valuation_amount,
|
||||||
|
self.precision("item_tax_amount", item))
|
||||||
|
valuation_amount_adjustment -= item.item_tax_amount
|
||||||
|
|
||||||
if item.item_code and item.qty:
|
|
||||||
self.round_floats_in(item)
|
self.round_floats_in(item)
|
||||||
|
|
||||||
# if no item code, which is sometimes the case in purchase invoice,
|
item.conversion_factor = item.conversion_factor or flt(webnotes.conn.get_value(
|
||||||
# then it is not possible to track valuation against it
|
"UOM Conversion Detail", {"parent": item.item_code, "uom": item.uom},
|
||||||
|
"conversion_factor")) or 1
|
||||||
qty_in_stock_uom = flt(item.qty * item.conversion_factor)
|
qty_in_stock_uom = flt(item.qty * item.conversion_factor)
|
||||||
item.valuation_rate = ((item.amount + item.item_tax_amount + item.rm_supp_cost)
|
item.valuation_rate = ((item.amount + item.item_tax_amount + item.rm_supp_cost)
|
||||||
/ qty_in_stock_uom)
|
/ qty_in_stock_uom)
|
||||||
|
@ -191,7 +191,8 @@ class SellingController(StockController):
|
|||||||
|
|
||||||
self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total,
|
self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total,
|
||||||
self.precision("other_charges_total"))
|
self.precision("other_charges_total"))
|
||||||
self.doc.other_charges_total_export = flt(self.doc.grand_total_export - self.doc.net_total_export,
|
self.doc.other_charges_total_export = flt(
|
||||||
|
self.doc.grand_total_export - self.doc.net_total_export,
|
||||||
self.precision("other_charges_total_export"))
|
self.precision("other_charges_total_export"))
|
||||||
|
|
||||||
self.doc.rounded_total = _round(self.doc.grand_total)
|
self.doc.rounded_total = _round(self.doc.grand_total)
|
||||||
|
@ -151,7 +151,9 @@ class StatusUpdater(DocListController):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# check if overflow is within tolerance
|
# check if overflow is within tolerance
|
||||||
tolerance = self.get_tolerance_for(item['item_code'])
|
tolerance, self.tolerance, self.global_tolerance = get_tolerance_for(item['item_code'],
|
||||||
|
self.tolerance, self.global_tolerance)
|
||||||
|
|
||||||
overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) /
|
overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) /
|
||||||
item[args['target_ref_field']]) * 100
|
item[args['target_ref_field']]) * 100
|
||||||
|
|
||||||
@ -171,23 +173,6 @@ class StatusUpdater(DocListController):
|
|||||||
Also, please check if the order item has already been billed in the Sales Order""" %
|
Also, please check if the order item has already been billed in the Sales Order""" %
|
||||||
item, raise_exception=1)
|
item, raise_exception=1)
|
||||||
|
|
||||||
def get_tolerance_for(self, item_code):
|
|
||||||
"""
|
|
||||||
Returns the tolerance for the item, if not set, returns global tolerance
|
|
||||||
"""
|
|
||||||
if self.tolerance.get(item_code): return self.tolerance[item_code]
|
|
||||||
|
|
||||||
tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0)
|
|
||||||
|
|
||||||
if not tolerance:
|
|
||||||
if self.global_tolerance == None:
|
|
||||||
self.global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None,
|
|
||||||
'tolerance'))
|
|
||||||
tolerance = self.global_tolerance
|
|
||||||
|
|
||||||
self.tolerance[item_code] = tolerance
|
|
||||||
return tolerance
|
|
||||||
|
|
||||||
|
|
||||||
def update_qty(self, change_modified=True):
|
def update_qty(self, change_modified=True):
|
||||||
"""
|
"""
|
||||||
@ -246,3 +231,58 @@ class StatusUpdater(DocListController):
|
|||||||
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
|
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
|
||||||
'Fully %(keyword)s', 'Partly %(keyword)s'))
|
'Fully %(keyword)s', 'Partly %(keyword)s'))
|
||||||
where name='%(name)s'""" % args)
|
where name='%(name)s'""" % args)
|
||||||
|
|
||||||
|
|
||||||
|
def update_billing_status_for_zero_amount_refdoc(self, ref_dt):
|
||||||
|
ref_fieldname = ref_dt.lower().replace(" ", "_")
|
||||||
|
zero_amount_refdoc = []
|
||||||
|
all_zero_amount_refdoc = webnotes.conn.sql_list("""select name from `tab%s`
|
||||||
|
where docstatus=1 and net_total = 0""" % ref_dt)
|
||||||
|
|
||||||
|
for item in self.doclist.get({"parentfield": "entries"}):
|
||||||
|
if item.fields.get(ref_fieldname) \
|
||||||
|
and item.fields.get(ref_fieldname) in all_zero_amount_refdoc \
|
||||||
|
and item.fields.get(ref_fieldname) not in zero_amount_refdoc:
|
||||||
|
zero_amount_refdoc.append(item.fields[ref_fieldname])
|
||||||
|
|
||||||
|
if zero_amount_refdoc:
|
||||||
|
self.update_biling_status(zero_amount_refdoc, ref_dt, ref_fieldname)
|
||||||
|
|
||||||
|
def update_biling_status(self, zero_amount_refdoc, ref_dt, ref_fieldname):
|
||||||
|
for ref_dn in zero_amount_refdoc:
|
||||||
|
ref_doc_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0)) from `tab%s Item`
|
||||||
|
where parent=%s""" % (ref_dt, '%s'), (ref_dn))[0][0])
|
||||||
|
|
||||||
|
billed_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0))
|
||||||
|
from `tab%s Item` where %s=%s and docstatus=1""" %
|
||||||
|
(self.doc.doctype, ref_fieldname, '%s'), (ref_dn))[0][0])
|
||||||
|
|
||||||
|
per_billed = ((ref_doc_qty if billed_qty > ref_doc_qty else billed_qty)\
|
||||||
|
/ ref_doc_qty)*100
|
||||||
|
webnotes.conn.set_value(ref_dt, ref_dn, "per_billed", per_billed)
|
||||||
|
|
||||||
|
from webnotes.model.meta import has_field
|
||||||
|
if has_field(ref_dt, "billing_status"):
|
||||||
|
if per_billed < 0.001: billing_status = "Not Billed"
|
||||||
|
elif per_billed >= 99.99: billing_status = "Fully Billed"
|
||||||
|
else: billing_status = "Partly Billed"
|
||||||
|
|
||||||
|
webnotes.conn.set_value(ref_dt, ref_dn, "billing_status", billing_status)
|
||||||
|
|
||||||
|
def get_tolerance_for(item_code, item_tolerance={}, global_tolerance=None):
|
||||||
|
"""
|
||||||
|
Returns the tolerance for the item, if not set, returns global tolerance
|
||||||
|
"""
|
||||||
|
if item_tolerance.get(item_code):
|
||||||
|
return item_tolerance[item_code], item_tolerance, global_tolerance
|
||||||
|
|
||||||
|
tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0)
|
||||||
|
|
||||||
|
if not tolerance:
|
||||||
|
if global_tolerance == None:
|
||||||
|
global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None,
|
||||||
|
'tolerance'))
|
||||||
|
tolerance = global_tolerance
|
||||||
|
|
||||||
|
item_tolerance[item_code] = tolerance
|
||||||
|
return tolerance, item_tolerance, global_tolerance
|
@ -43,7 +43,7 @@ cur_frm.cscript.make_jv = function(doc, dt, dn) {
|
|||||||
jv = locals['Journal Voucher'][jv];
|
jv = locals['Journal Voucher'][jv];
|
||||||
jv.voucher_type = 'Bank Voucher';
|
jv.voucher_type = 'Bank Voucher';
|
||||||
jv.user_remark = wn._('Payment of salary for the month: ') + doc.month +
|
jv.user_remark = wn._('Payment of salary for the month: ') + doc.month +
|
||||||
wn._('and fiscal year: ') + doc.fiscal_year;
|
wn._(' and fiscal year: ') + doc.fiscal_year;
|
||||||
jv.fiscal_year = doc.fiscal_year;
|
jv.fiscal_year = doc.fiscal_year;
|
||||||
jv.company = doc.company;
|
jv.company = doc.company;
|
||||||
jv.posting_date = dateutil.obj_to_str(new Date());
|
jv.posting_date = dateutil.obj_to_str(new Date());
|
||||||
|
@ -7,7 +7,7 @@ wn.query_reports["Monthly Salary Register"] = {
|
|||||||
"fieldname":"month",
|
"fieldname":"month",
|
||||||
"label": wn._("Month"),
|
"label": wn._("Month"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec",
|
"options": "\nJan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec",
|
||||||
"default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
"default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
||||||
"Dec"][wn.datetime.str_to_obj(wn.datetime.get_today()).getMonth()],
|
"Dec"][wn.datetime.str_to_obj(wn.datetime.get_today()).getMonth()],
|
||||||
},
|
},
|
||||||
|
@ -50,17 +50,17 @@ def get_columns(salary_slips):
|
|||||||
where ifnull(d_modified_amount, 0) != 0 and parent in (%s)""" %
|
where ifnull(d_modified_amount, 0) != 0 and parent in (%s)""" %
|
||||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]))
|
||||||
|
|
||||||
columns = columns + [(e + ":Link/Earning Type:120") for e in earning_types] + \
|
columns = columns + [(e + ":Currency:120") for e in earning_types] + \
|
||||||
["Arrear Amount:Currency:120", "Leave Encashment Amount:Currency:150",
|
["Arrear Amount:Currency:120", "Leave Encashment Amount:Currency:150",
|
||||||
"Gross Pay:Currency:120"] + [(d + ":Link/Deduction Type:120") for d in ded_types] + \
|
"Gross Pay:Currency:120"] + [(d + ":Currency:120") for d in ded_types] + \
|
||||||
["Total Deduction:Currency:120", "Net Pay:Currency:120"]
|
["Total Deduction:Currency:120", "Net Pay:Currency:120"]
|
||||||
|
|
||||||
return columns, earning_types, ded_types
|
return columns, earning_types, ded_types
|
||||||
|
|
||||||
def get_salary_slips(filters):
|
def get_salary_slips(filters):
|
||||||
conditions, filters = get_conditions(filters)
|
conditions, filters = get_conditions(filters)
|
||||||
salary_slips = webnotes.conn.sql("""select * from `tabSalary Slip` where docstatus = 1 %s""" %
|
salary_slips = webnotes.conn.sql("""select * from `tabSalary Slip` where docstatus = 1 %s
|
||||||
conditions, filters, as_dict=1)
|
order by employee, month""" % conditions, filters, as_dict=1)
|
||||||
|
|
||||||
if not salary_slips:
|
if not salary_slips:
|
||||||
msgprint(_("No salary slip found for month: ") + cstr(filters.get("month")) +
|
msgprint(_("No salary slip found for month: ") + cstr(filters.get("month")) +
|
||||||
@ -102,6 +102,6 @@ def get_ss_ded_map(salary_slips):
|
|||||||
ss_ded_map = {}
|
ss_ded_map = {}
|
||||||
for d in ss_deductions:
|
for d in ss_deductions:
|
||||||
ss_ded_map.setdefault(d.parent, webnotes._dict()).setdefault(d.d_type, [])
|
ss_ded_map.setdefault(d.parent, webnotes._dict()).setdefault(d.d_type, [])
|
||||||
ss_ded_map[d.parent][d.e_type] = flt(d.d_modified_amount)
|
ss_ded_map[d.parent][d.d_type] = flt(d.d_modified_amount)
|
||||||
|
|
||||||
return ss_ded_map
|
return ss_ded_map
|
@ -35,6 +35,8 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
stock_entry = webnotes.bean(stock_entry)
|
stock_entry = webnotes.bean(stock_entry)
|
||||||
stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013"
|
stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013"
|
||||||
stock_entry.doc.fg_completed_qty = 4
|
stock_entry.doc.fg_completed_qty = 4
|
||||||
|
stock_entry.doc.posting_date = "2013-05-12"
|
||||||
|
stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013"
|
||||||
stock_entry.run_method("get_items")
|
stock_entry.run_method("get_items")
|
||||||
stock_entry.submit()
|
stock_entry.submit()
|
||||||
|
|
||||||
@ -51,6 +53,7 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
|
|
||||||
stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
|
stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
|
||||||
stock_entry = webnotes.bean(stock_entry)
|
stock_entry = webnotes.bean(stock_entry)
|
||||||
|
stock_entry.doc.posting_date = "2013-05-12"
|
||||||
stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013"
|
stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013"
|
||||||
stock_entry.doc.fg_completed_qty = 15
|
stock_entry.doc.fg_completed_qty = 15
|
||||||
stock_entry.run_method("get_items")
|
stock_entry.run_method("get_items")
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2014, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
webnotes.reload_doc("stock", "doctype", "price_list")
|
||||||
|
webnotes.reload_doc("stock", "doctype", "item_price")
|
||||||
|
|
||||||
|
if "buying_or_selling" in webnotes.conn.get_table_columns("Price List"):
|
||||||
|
webnotes.conn.sql("""update `tabPrice List` set
|
||||||
|
selling =
|
||||||
|
case
|
||||||
|
when buying_or_selling='Selling'
|
||||||
|
then 1
|
||||||
|
end,
|
||||||
|
buying =
|
||||||
|
case
|
||||||
|
when buying_or_selling='Buying'
|
||||||
|
then 1
|
||||||
|
end
|
||||||
|
""")
|
||||||
|
webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl
|
||||||
|
set ip.buying=pl.buying, ip.selling=pl.selling
|
||||||
|
where ip.price_list=pl.name""")
|
||||||
|
|
||||||
|
webnotes.conn.sql("""update `tabItem Price` set selling=1 where ifnull(selling, 0)=0 and
|
||||||
|
ifnull(buying, 0)=0""")
|
@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
import webnotes
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
webnotes.reload_doc("core", "doctype", "custom_field")
|
||||||
|
|
||||||
|
cf_doclist = webnotes.get_doctype("Custom Field")
|
||||||
|
|
||||||
|
delete_list = []
|
||||||
|
for d in webnotes.conn.sql("""select cf.name as cf_name, ps.property,
|
||||||
|
ps.value, ps.name as ps_name
|
||||||
|
from `tabProperty Setter` ps, `tabCustom Field` cf
|
||||||
|
where ps.doctype_or_field = 'DocField' and ps.property != 'previous_field'
|
||||||
|
and ps.doc_type=cf.dt and ps.field_name=cf.fieldname""", as_dict=1):
|
||||||
|
if cf_doclist.get_field(d.property):
|
||||||
|
webnotes.conn.sql("""update `tabCustom Field`
|
||||||
|
set `%s`=%s where name=%s""" % (d.property, '%s', '%s'), (d.value, d.cf_name))
|
||||||
|
|
||||||
|
delete_list.append(d.ps_name)
|
||||||
|
|
||||||
|
if delete_list:
|
||||||
|
webnotes.conn.sql("""delete from `tabProperty Setter` where name in (%s)""" %
|
||||||
|
', '.join(['%s']*len(delete_list)), tuple(delete_list))
|
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
import webnotes
|
||||||
|
from webnotes.utils import flt
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
for order_type in ["Sales", "Purchase"]:
|
||||||
|
for d in webnotes.conn.sql("""select par.name, sum(ifnull(child.qty, 0)) as total_qty
|
||||||
|
from `tab%s Order` par, `tab%s Order Item` child
|
||||||
|
where par.name = child.parent and par.docstatus = 1
|
||||||
|
and ifnull(par.net_total, 0) = 0 group by par.name""" %
|
||||||
|
(order_type, order_type), as_dict=1):
|
||||||
|
|
||||||
|
billed_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0))
|
||||||
|
from `tab%s Invoice Item` where %s=%s and docstatus=1""" %
|
||||||
|
(order_type, "sales_order" if order_type=="Sales" else "purchase_order", '%s'),
|
||||||
|
(d.name))[0][0])
|
||||||
|
|
||||||
|
per_billed = ((d.total_qty if billed_qty > d.total_qty else billed_qty)\
|
||||||
|
/ d.total_qty)*100
|
||||||
|
webnotes.conn.set_value(order_type+ " Order", d.name, "per_billed", per_billed)
|
||||||
|
|
||||||
|
if order_type == "Sales":
|
||||||
|
if per_billed < 0.001: billing_status = "Not Billed"
|
||||||
|
elif per_billed >= 99.99: billing_status = "Fully Billed"
|
||||||
|
else: billing_status = "Partly Billed"
|
||||||
|
|
||||||
|
webnotes.conn.set_value("Sales Order", d.name, "billing_status", billing_status)
|
@ -9,19 +9,6 @@ def execute():
|
|||||||
webnotes.reload_doc("stock", "doctype", "price_list")
|
webnotes.reload_doc("stock", "doctype", "price_list")
|
||||||
webnotes.reload_doc("stock", "doctype", "item_price")
|
webnotes.reload_doc("stock", "doctype", "item_price")
|
||||||
|
|
||||||
try:
|
webnotes.conn.sql("""update `tabPrice List` pl, `tabItem Price` ip
|
||||||
for price_list in webnotes.conn.sql_list("""select name from `tabPrice List`"""):
|
set pl.selling=ip.selling, pl.buying=ip.buying
|
||||||
buying, selling = False, False
|
where pl.name=ip.price_list_name""")
|
||||||
for b, s in webnotes.conn.sql("""select distinct buying, selling
|
|
||||||
from `tabItem Price` where price_list_name=%s""", price_list):
|
|
||||||
buying = buying or cint(b)
|
|
||||||
selling = selling or cint(s)
|
|
||||||
|
|
||||||
buying_or_selling = "Selling" if selling else "Buying"
|
|
||||||
webnotes.conn.set_value("Price List", price_list, "buying_or_selling", buying_or_selling)
|
|
||||||
except webnotes.SQLError, e:
|
|
||||||
if e.args[0] == 1054:
|
|
||||||
webnotes.conn.sql("""update `tabPrice List` set buying_or_selling='Selling'
|
|
||||||
where ifnull(buying_or_selling, '')='' """)
|
|
||||||
else:
|
|
||||||
raise
|
|
@ -12,9 +12,7 @@ def execute():
|
|||||||
where ip.item_code=i.name""")
|
where ip.item_code=i.name""")
|
||||||
|
|
||||||
webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl
|
webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl
|
||||||
set ip.price_list=pl.name, ip.currency=pl.currency,
|
set ip.price_list=pl.name, ip.currency=pl.currency where ip.parent=pl.name""")
|
||||||
ip.buying_or_selling=pl.buying_or_selling
|
|
||||||
where ip.parent=pl.name""")
|
|
||||||
|
|
||||||
webnotes.conn.sql("""update `tabItem Price`
|
webnotes.conn.sql("""update `tabItem Price`
|
||||||
set parent=null, parenttype=null, parentfield=null, idx=null""")
|
set parent=null, parenttype=null, parentfield=null, idx=null""")
|
@ -262,4 +262,7 @@ patch_list = [
|
|||||||
"execute:webnotes.delete_doc('DocType', 'Warehouse Type')",
|
"execute:webnotes.delete_doc('DocType', 'Warehouse Type')",
|
||||||
"patches.1312.p01_delete_old_stock_reports",
|
"patches.1312.p01_delete_old_stock_reports",
|
||||||
"patches.1312.p02_update_item_details_in_item_price",
|
"patches.1312.p02_update_item_details_in_item_price",
|
||||||
|
"patches.1401.p01_move_related_property_setters_to_custom_field",
|
||||||
|
"patches.1401.p01_make_buying_selling_as_check_box_in_price_list",
|
||||||
|
"patches.1401.update_billing_status_for_zero_value_order",
|
||||||
]
|
]
|
@ -24,14 +24,16 @@ $(document).bind('toolbar_setup', function() {
|
|||||||
wn.provide('wn.ui.misc');
|
wn.provide('wn.ui.misc');
|
||||||
wn.ui.misc.about = function() {
|
wn.ui.misc.about = function() {
|
||||||
if(!wn.ui.misc.about_dialog) {
|
if(!wn.ui.misc.about_dialog) {
|
||||||
var d = new wn.ui.Dialog({title: wn._('About ERPNext')})
|
var d = new wn.ui.Dialog({title: wn._('About')})
|
||||||
|
|
||||||
$(d.body).html(repl("<div>\
|
$(d.body).html(repl("<div>\
|
||||||
<p>"+wn._("ERPNext is an open-source web based ERP made by Web Notes Technologies Pvt Ltd. to provide an integrated tool to manage most processes in a small organization. For more information about Web Notes, or to buy hosting servies, go to ")+
|
<h2>ERPNext</h2> \
|
||||||
"<a href='https://erpnext.com'>https://erpnext.com</a>.</p>\
|
<p>"+wn._("An open source ERP made for the web.</p>") +
|
||||||
<p>"+wn._("To report an issue, go to ")+"<a href='https://github.com/webnotes/erpnext/issues'>GitHub Issues</a></p>\
|
"<p>"+wn._("To report an issue, go to ")+"<a href='https://github.com/webnotes/erpnext/issues'>GitHub Issues</a></p> \
|
||||||
<hr>\
|
<p><a href='http://erpnext.org' target='_blank'>http://erpnext.org</a>.</p>\
|
||||||
<p><a href='http://www.gnu.org/copyleft/gpl.html'>License: GNU General Public License Version 3</a></p>\
|
<p><a href='http://www.gnu.org/copyleft/gpl.html'>License: GNU General Public License Version 3</a></p>\
|
||||||
|
<hr>\
|
||||||
|
<p>© 2014 Web Notes Technologies Pvt. Ltd and contributers </p> \
|
||||||
</div>", wn.app));
|
</div>", wn.app));
|
||||||
|
|
||||||
wn.ui.misc.about_dialog = d;
|
wn.ui.misc.about_dialog = d;
|
||||||
|
@ -28,7 +28,8 @@ erpnext.stock.StockController = wn.ui.form.Controller.extend({
|
|||||||
voucher_no: me.frm.doc.name,
|
voucher_no: me.frm.doc.name,
|
||||||
from_date: me.frm.doc.posting_date,
|
from_date: me.frm.doc.posting_date,
|
||||||
to_date: me.frm.doc.posting_date,
|
to_date: me.frm.doc.posting_date,
|
||||||
company: me.frm.doc.company
|
company: me.frm.doc.company,
|
||||||
|
group_by_voucher: false
|
||||||
};
|
};
|
||||||
wn.set_route("query-report", "General Ledger");
|
wn.set_route("query-report", "General Ledger");
|
||||||
}, "icon-table");
|
}, "icon-table");
|
||||||
|
@ -21,6 +21,6 @@ erpnext.toolbar.setup = function() {
|
|||||||
<i class="icon-fixed-width icon-comments"></i> '+wn._('Live Chat')+'</a></li>');
|
<i class="icon-fixed-width icon-comments"></i> '+wn._('Live Chat')+'</a></li>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#toolbar-tools").append('<li><a href="#latest-updates">\
|
$("#toolbar-tools").append('<li><a href="https://github.com/webnotes/erpnext/releases" target="_blank">\
|
||||||
<i class="icon-fixed-width icon-rss"></i> Latest Updates</li>');
|
<i class="icon-fixed-width icon-rss"></i> Latest Updates</li>');
|
||||||
}
|
}
|
@ -330,8 +330,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
doctype: tax.doctype,
|
doctype: tax.doctype,
|
||||||
row_id_label: wn.meta.get_label(tax.doctype, "row_id", tax.name)
|
row_id_label: wn.meta.get_label(tax.doctype, "row_id", tax.name)
|
||||||
});
|
});
|
||||||
msgprint(msg);
|
wn.throw(msg);
|
||||||
throw msg;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -347,8 +346,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
charge_type_label: wn.meta.get_label(tax.doctype, "charge_type", tax.name),
|
charge_type_label: wn.meta.get_label(tax.doctype, "charge_type", tax.name),
|
||||||
charge_type: tax.charge_type
|
charge_type: tax.charge_type
|
||||||
});
|
});
|
||||||
msgprint(msg);
|
wn.throw(msg);
|
||||||
throw msg;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var on_previous_row_error = function(row_range) {
|
var on_previous_row_error = function(row_range) {
|
||||||
@ -363,8 +361,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
row_range: row_range,
|
row_range: row_range,
|
||||||
});
|
});
|
||||||
|
|
||||||
msgprint(msg);
|
wn.throw(msg);
|
||||||
throw msg;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(cint(tax.included_in_print_rate)) {
|
if(cint(tax.included_in_print_rate)) {
|
||||||
@ -543,6 +540,14 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
|
|
||||||
calculate_taxes: function() {
|
calculate_taxes: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
var actual_tax_dict = {};
|
||||||
|
|
||||||
|
// maintain actual tax rate based on idx
|
||||||
|
$.each(this.frm.tax_doclist, function(i, tax) {
|
||||||
|
if (tax.charge_type == "Actual") {
|
||||||
|
actual_tax_dict[tax.idx] = flt(tax.rate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$.each(this.frm.item_doclist, function(n, item) {
|
$.each(this.frm.item_doclist, function(n, item) {
|
||||||
var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
|
var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
|
||||||
@ -553,14 +558,14 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
|
|
||||||
me.set_item_tax_amount && me.set_item_tax_amount(item, tax, current_tax_amount);
|
me.set_item_tax_amount && me.set_item_tax_amount(item, tax, current_tax_amount);
|
||||||
|
|
||||||
// case when net total is 0 but there is an actual type charge
|
// Adjust divisional loss to the last item
|
||||||
// in this case add the actual amount to tax.tax_amount
|
if (tax.charge_type == "Actual") {
|
||||||
// and tax.grand_total_for_current_item for the first such iteration
|
actual_tax_dict[tax.idx] -= current_tax_amount;
|
||||||
if(tax.charge_type == "Actual" &&
|
if (n == me.frm.item_doclist.length - 1) {
|
||||||
!(current_tax_amount || me.frm.doc.net_total || tax.tax_amount)) {
|
current_tax_amount += actual_tax_dict[tax.idx]
|
||||||
var zero_net_total_adjustment = flt(tax.rate, precision("tax_amount", tax));
|
|
||||||
current_tax_amount += zero_net_total_adjustment;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// store tax_amount for current item as it will be used for
|
// store tax_amount for current item as it will be used for
|
||||||
// charge type = 'On Previous Row Amount'
|
// charge type = 'On Previous Row Amount'
|
||||||
@ -592,6 +597,11 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
|
|
||||||
// in tax.total, accumulate grand total for each item
|
// in tax.total, accumulate grand total for each item
|
||||||
tax.total += tax.grand_total_for_current_item;
|
tax.total += tax.grand_total_for_current_item;
|
||||||
|
|
||||||
|
if (n == me.frm.item_doclist.length - 1) {
|
||||||
|
tax.total = flt(tax.total, precision("total", tax));
|
||||||
|
tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", tax));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -1,13 +1,2 @@
|
|||||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------- ONLOAD -------------
|
|
||||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
|
||||||
|
|
||||||
}
|
|
@ -2,12 +2,13 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-01-10 16:34:18",
|
"creation": "2013-01-10 16:34:18",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 19:23:58",
|
"modified": "2014-01-16 12:52:19",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
|
"allow_rename": 1,
|
||||||
"autoname": "field:campaign_name",
|
"autoname": "field:campaign_name",
|
||||||
"description": "Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ",
|
"description": "Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
|
@ -122,6 +122,6 @@ cur_frm.fields_dict.lead_name.get_query = function(doc,cdt,cdn) {
|
|||||||
|
|
||||||
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) {
|
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) {
|
||||||
return{
|
return{
|
||||||
filters:{'buying_or_selling': "Selling"}
|
filters:{'selling': 1}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ class TestQuotation(unittest.TestCase):
|
|||||||
|
|
||||||
sales_order[0]["delivery_date"] = "2014-01-01"
|
sales_order[0]["delivery_date"] = "2014-01-01"
|
||||||
sales_order[0]["naming_series"] = "_T-Quotation-"
|
sales_order[0]["naming_series"] = "_T-Quotation-"
|
||||||
|
sales_order[0]["transaction_date"] = "2013-05-12"
|
||||||
webnotes.bean(sales_order).insert()
|
webnotes.bean(sales_order).insert()
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
self.assertEquals(len([d for d in si if d["doctype"]=="Sales Invoice Item"]), 1)
|
self.assertEquals(len([d for d in si if d["doctype"]=="Sales Invoice Item"]), 1)
|
||||||
|
|
||||||
si = webnotes.bean(si)
|
si = webnotes.bean(si)
|
||||||
|
si.doc.posting_date = "2013-10-10"
|
||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
|
|
||||||
if(this.frm.fields_dict.selling_price_list) {
|
if(this.frm.fields_dict.selling_price_list) {
|
||||||
this.frm.set_query("selling_price_list", function() {
|
this.frm.set_query("selling_price_list", function() {
|
||||||
return { filters: { buying_or_selling: "Selling" } };
|
return { filters: { selling: 1 } };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import msgprint, _
|
from webnotes import _, throw
|
||||||
from webnotes.utils import flt, cint, comma_and
|
from webnotes.utils import flt, cint
|
||||||
import json
|
import json
|
||||||
|
|
||||||
def get_customer_list(doctype, txt, searchfield, start, page_len, filters):
|
def get_customer_list(doctype, txt, searchfield, start, page_len, filters):
|
||||||
@ -100,7 +100,7 @@ def _get_item_code(barcode=None, serial_no=None):
|
|||||||
where name=%s""", serial_no)
|
where name=%s""", serial_no)
|
||||||
|
|
||||||
if not item_code:
|
if not item_code:
|
||||||
msgprint(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no), raise_exception=True)
|
throw(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no))
|
||||||
|
|
||||||
return item_code[0]
|
return item_code[0]
|
||||||
|
|
||||||
@ -111,22 +111,26 @@ def _validate_item_details(args, item):
|
|||||||
# validate if sales item or service item
|
# validate if sales item or service item
|
||||||
if args.order_type == "Maintenance":
|
if args.order_type == "Maintenance":
|
||||||
if item.is_service_item != "Yes":
|
if item.is_service_item != "Yes":
|
||||||
msgprint(_("Item") + (" %s: " % item.name) +
|
throw(_("Item") + (" %s: " % item.name) +
|
||||||
_("not a service item.") +
|
_("not a service item.") +
|
||||||
_("Please select a service item or change the order type to Sales."),
|
_("Please select a service item or change the order type to Sales."))
|
||||||
raise_exception=True)
|
|
||||||
|
|
||||||
elif item.is_sales_item != "Yes":
|
elif item.is_sales_item != "Yes":
|
||||||
msgprint(_("Item") + (" %s: " % item.name) + _("not a sales item"),
|
throw(_("Item") + (" %s: " % item.name) + _("not a sales item"))
|
||||||
raise_exception=True)
|
|
||||||
|
|
||||||
def _get_basic_details(args, item_bean, warehouse_fieldname):
|
def _get_basic_details(args, item_bean, warehouse_fieldname):
|
||||||
item = item_bean.doc
|
item = item_bean.doc
|
||||||
|
|
||||||
|
from webnotes.defaults import get_user_default_as_list
|
||||||
|
user_default_warehouse_list = get_user_default_as_list('warehouse')
|
||||||
|
user_default_warehouse = user_default_warehouse_list[0] \
|
||||||
|
if len(user_default_warehouse_list)==1 else ""
|
||||||
|
|
||||||
out = webnotes._dict({
|
out = webnotes._dict({
|
||||||
"item_code": item.name,
|
"item_code": item.name,
|
||||||
"description": item.description_html or item.description,
|
"description": item.description_html or item.description,
|
||||||
warehouse_fieldname: item.default_warehouse or args.get(warehouse_fieldname),
|
warehouse_fieldname: user_default_warehouse or item.default_warehouse \
|
||||||
|
or args.get(warehouse_fieldname),
|
||||||
"income_account": item.default_income_account or args.income_account \
|
"income_account": item.default_income_account or args.income_account \
|
||||||
or webnotes.conn.get_value("Company", args.company, "default_income_account"),
|
or webnotes.conn.get_value("Company", args.company, "default_income_account"),
|
||||||
"expense_account": item.purchase_account or args.expense_account \
|
"expense_account": item.purchase_account or args.expense_account \
|
||||||
@ -147,7 +151,7 @@ def _get_basic_details(args, item_bean, warehouse_fieldname):
|
|||||||
|
|
||||||
def _get_price_list_rate(args, item_bean, meta):
|
def _get_price_list_rate(args, item_bean, meta):
|
||||||
ref_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
ref_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||||
where price_list=%s and item_code=%s and buying_or_selling='Selling'""",
|
where price_list=%s and item_code=%s and selling=1""",
|
||||||
(args.selling_price_list, args.item_code), as_dict=1)
|
(args.selling_price_list, args.item_code), as_dict=1)
|
||||||
|
|
||||||
if not ref_rate:
|
if not ref_rate:
|
||||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import _, msgprint
|
from webnotes import _, msgprint
|
||||||
|
|
||||||
from webnotes.utils import cstr
|
from webnotes.utils import cstr, cint
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
|
|
||||||
|
|
||||||
@ -237,21 +237,24 @@ class DocType:
|
|||||||
account.insert()
|
account.insert()
|
||||||
|
|
||||||
def set_default_accounts(self):
|
def set_default_accounts(self):
|
||||||
accounts = {
|
def _set_default_accounts(accounts):
|
||||||
"default_income_account": "Sales",
|
for a in accounts:
|
||||||
"default_expense_account": "Cost of Goods Sold",
|
account_name = accounts[a] + " - " + self.doc.abbr
|
||||||
|
if not self.doc.fields.get(a) and webnotes.conn.exists("Account", account_name):
|
||||||
|
webnotes.conn.set(self.doc, a, account_name)
|
||||||
|
|
||||||
|
_set_default_accounts({
|
||||||
"receivables_group": "Accounts Receivable",
|
"receivables_group": "Accounts Receivable",
|
||||||
"payables_group": "Accounts Payable",
|
"payables_group": "Accounts Payable",
|
||||||
"default_cash_account": "Cash",
|
"default_cash_account": "Cash"
|
||||||
"stock_received_but_not_billed": "Stock Received But Not Billed",
|
})
|
||||||
"stock_adjustment_account": "Stock Adjustment",
|
|
||||||
"expenses_included_in_valuation": "Expenses Included In Valuation"
|
|
||||||
}
|
|
||||||
|
|
||||||
for a in accounts:
|
if cint(webnotes.conn.get_value("Accounts Settings", None, "auto_accounting_for_stock")):
|
||||||
account_name = accounts[a] + " - " + self.doc.abbr
|
_set_default_accounts({
|
||||||
if not self.doc.fields.get(a) and webnotes.conn.exists("Account", account_name):
|
"stock_received_but_not_billed": "Stock Received But Not Billed",
|
||||||
webnotes.conn.set(self.doc, a, account_name)
|
"stock_adjustment_account": "Stock Adjustment",
|
||||||
|
"expenses_included_in_valuation": "Expenses Included In Valuation"
|
||||||
|
})
|
||||||
|
|
||||||
def create_default_cost_center(self):
|
def create_default_cost_center(self):
|
||||||
cc_list = [
|
cc_list = [
|
||||||
|
@ -98,7 +98,8 @@ def create_price_lists(args):
|
|||||||
{
|
{
|
||||||
"doctype": "Price List",
|
"doctype": "Price List",
|
||||||
"price_list_name": "Standard " + pl_type,
|
"price_list_name": "Standard " + pl_type,
|
||||||
"buying_or_selling": pl_type,
|
"buying": 1 if pl_type == "Buying" else 0,
|
||||||
|
"selling": 1 if pl_type == "Selling" else 0,
|
||||||
"currency": args["currency"]
|
"currency": args["currency"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -29,10 +29,7 @@ cur_frm.cscript.make_dashboard = function() {
|
|||||||
|
|
||||||
cur_frm.cscript.edit_prices_button = function() {
|
cur_frm.cscript.edit_prices_button = function() {
|
||||||
cur_frm.add_custom_button("Add / Edit Prices", function() {
|
cur_frm.add_custom_button("Add / Edit Prices", function() {
|
||||||
wn.route_options = {
|
wn.set_route("Report", "Item Price", {"item_code": cur_frm.doc.name});
|
||||||
"item_code": cur_frm.doc.name
|
|
||||||
};
|
|
||||||
wn.set_route("Report", "Item Price");
|
|
||||||
}, "icon-money");
|
}, "icon-money");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
$.extend(cur_frm.cscript, {
|
$.extend(cur_frm.cscript, {
|
||||||
|
|
||||||
onload: function () {
|
onload: function () {
|
||||||
|
|
||||||
// Fetch price list details
|
// Fetch price list details
|
||||||
cur_frm.add_fetch("price_list", "buying_or_selling", "buying_or_selling");
|
cur_frm.add_fetch("price_list", "buying", "buying");
|
||||||
|
cur_frm.add_fetch("price_list", "selling", "selling");
|
||||||
cur_frm.add_fetch("price_list", "currency", "currency");
|
cur_frm.add_fetch("price_list", "currency", "currency");
|
||||||
|
|
||||||
// Fetch item details
|
// Fetch item details
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
# MIT License. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
@ -19,8 +17,8 @@ class DocType:
|
|||||||
self.update_item_details()
|
self.update_item_details()
|
||||||
|
|
||||||
def update_price_list_details(self):
|
def update_price_list_details(self):
|
||||||
self.doc.buying_or_selling, self.doc.currency = webnotes.conn.get_value("Price List",
|
self.doc.buying, self.doc.selling, self.doc.currency = webnotes.conn.get_value("Price List",
|
||||||
self.doc.price_list, ["buying_or_selling", "currency"])
|
self.doc.price_list, ["buying", "selling", "currency"])
|
||||||
|
|
||||||
def update_item_details(self):
|
def update_item_details(self):
|
||||||
self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item",
|
self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-05-02 16:29:48",
|
"creation": "2013-05-02 16:29:48",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 19:24:10",
|
"modified": "2014-01-07 19:16:49",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -46,6 +46,13 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"name": "Item Price"
|
"name": "Item Price"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "price_list_details",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Price List",
|
||||||
|
"options": "icon-tags"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "price_list",
|
"fieldname": "price_list",
|
||||||
@ -55,6 +62,29 @@
|
|||||||
"options": "Price List",
|
"options": "Price List",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "buying",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Buying",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "selling",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Selling",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "item_details",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Item",
|
||||||
|
"options": "icon-tag"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
@ -86,16 +116,6 @@
|
|||||||
"fieldname": "col_br_1",
|
"fieldname": "col_br_1",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "buying_or_selling",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"in_filter": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Valid for Buying or Selling?",
|
|
||||||
"options": "Selling\nBuying",
|
|
||||||
"reqd": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
|
@ -125,6 +125,7 @@ class TestMaterialRequest(unittest.TestCase):
|
|||||||
from erpnext.stock.doctype.material_request.material_request import make_purchase_order
|
from erpnext.stock.doctype.material_request.material_request import make_purchase_order
|
||||||
po_doclist = make_purchase_order(mr.doc.name)
|
po_doclist = make_purchase_order(mr.doc.name)
|
||||||
po_doclist[0].supplier = "_Test Supplier"
|
po_doclist[0].supplier = "_Test Supplier"
|
||||||
|
po_doclist[0].transaction_date = "2013-07-07"
|
||||||
po_doclist[1].qty = 27.0
|
po_doclist[1].qty = 27.0
|
||||||
po_doclist[2].qty = 1.5
|
po_doclist[2].qty = 1.5
|
||||||
po_doclist[1].schedule_date = "2013-07-09"
|
po_doclist[1].schedule_date = "2013-07-09"
|
||||||
|
@ -3,16 +3,15 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import msgprint, _
|
from webnotes import msgprint, _, throw
|
||||||
from webnotes.utils import comma_or, cint
|
from webnotes.utils import cint
|
||||||
from webnotes.model.controller import DocListController
|
from webnotes.model.controller import DocListController
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
|
|
||||||
class DocType(DocListController):
|
class DocType(DocListController):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.doc.buying_or_selling not in ["Buying", "Selling"]:
|
if not cint(self.doc.buying) and not cint(self.doc.selling):
|
||||||
msgprint(_(self.meta.get_label("buying_or_selling")) + " " + _("must be one of") + " " +
|
throw(_("Price List must be applicable for Buying or Selling"))
|
||||||
comma_or(["Buying", "Selling"]), raise_exception=True)
|
|
||||||
|
|
||||||
if not self.doclist.get({"parentfield": "valid_for_territories"}):
|
if not self.doclist.get({"parentfield": "valid_for_territories"}):
|
||||||
# if no territory, set default territory
|
# if no territory, set default territory
|
||||||
@ -31,15 +30,15 @@ class DocType(DocListController):
|
|||||||
self.update_item_price()
|
self.update_item_price()
|
||||||
|
|
||||||
def set_default_if_missing(self):
|
def set_default_if_missing(self):
|
||||||
if self.doc.buying_or_selling=="Selling":
|
if cint(self.doc.selling):
|
||||||
if not webnotes.conn.get_value("Selling Settings", None, "selling_price_list"):
|
if not webnotes.conn.get_value("Selling Settings", None, "selling_price_list"):
|
||||||
webnotes.set_value("Selling Settings", "Selling Settings", "selling_price_list", self.doc.name)
|
webnotes.set_value("Selling Settings", "Selling Settings", "selling_price_list", self.doc.name)
|
||||||
|
|
||||||
elif self.doc.buying_or_selling=="Buying":
|
elif cint(self.doc.buying):
|
||||||
if not webnotes.conn.get_value("Buying Settings", None, "buying_price_list"):
|
if not webnotes.conn.get_value("Buying Settings", None, "buying_price_list"):
|
||||||
webnotes.set_value("Buying Settings", "Buying Settings", "buying_price_list", self.doc.name)
|
webnotes.set_value("Buying Settings", "Buying Settings", "buying_price_list", self.doc.name)
|
||||||
|
|
||||||
def update_item_price(self):
|
def update_item_price(self):
|
||||||
webnotes.conn.sql("""update `tabItem Price` set currency=%s,
|
webnotes.conn.sql("""update `tabItem Price` set currency=%s,
|
||||||
buying_or_selling=%s, modified=NOW() where price_list=%s""",
|
buying=%s, selling=%s, modified=NOW() where price_list=%s""",
|
||||||
(self.doc.currency, self.doc.buying_or_selling, self.doc.name))
|
(self.doc.currency, cint(self.doc.buying), cint(self.doc.selling), self.doc.name))
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-01-25 11:35:09",
|
"creation": "2013-01-25 11:35:09",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 18:28:50",
|
"modified": "2014-01-06 18:28:23",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -60,14 +60,19 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Selling",
|
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "buying_or_selling",
|
"fieldname": "buying",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Check",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Valid for Buying or Selling?",
|
"label": "Buying"
|
||||||
"options": "Buying\nSelling",
|
},
|
||||||
"reqd": 1
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "selling",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Selling",
|
||||||
|
"reqd": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
@ -12,7 +12,7 @@ test_records = [
|
|||||||
"doctype": "Price List",
|
"doctype": "Price List",
|
||||||
"price_list_name": "_Test Price List",
|
"price_list_name": "_Test Price List",
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"buying_or_selling": "Selling"
|
"selling": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Applicable Territory",
|
"doctype": "Applicable Territory",
|
||||||
@ -25,7 +25,7 @@ test_records = [
|
|||||||
"doctype": "Price List",
|
"doctype": "Price List",
|
||||||
"price_list_name": "_Test Price List 2",
|
"price_list_name": "_Test Price List 2",
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"buying_or_selling": "Selling"
|
"selling": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Applicable Territory",
|
"doctype": "Applicable Territory",
|
||||||
@ -38,7 +38,7 @@ test_records = [
|
|||||||
"doctype": "Price List",
|
"doctype": "Price List",
|
||||||
"price_list_name": "_Test Price List India",
|
"price_list_name": "_Test Price List India",
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"buying_or_selling": "Selling"
|
"selling": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Applicable Territory",
|
"doctype": "Applicable Territory",
|
||||||
@ -51,7 +51,7 @@ test_records = [
|
|||||||
"doctype": "Price List",
|
"doctype": "Price List",
|
||||||
"price_list_name": "_Test Price List Rest of the World",
|
"price_list_name": "_Test Price List Rest of the World",
|
||||||
"currency": "USD",
|
"currency": "USD",
|
||||||
"buying_or_selling": "Selling"
|
"selling": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Applicable Territory",
|
"doctype": "Applicable Territory",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-05-24 19:29:10",
|
"creation": "2013-05-24 19:29:10",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 19:23:36",
|
"modified": "2014-01-15 16:00:44",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -334,6 +334,16 @@
|
|||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0
|
"reqd": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default": ":Company",
|
||||||
|
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Cost Center",
|
||||||
|
"options": "Cost Center",
|
||||||
|
"print_hide": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "project_name",
|
"fieldname": "project_name",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-03-29 18:22:12",
|
"creation": "2013-03-29 18:22:12",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 19:21:48",
|
"modified": "2014-01-15 16:08:45",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -165,7 +165,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
|
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "expense_account",
|
"fieldname": "expense_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@ -175,7 +175,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": ":Company",
|
"default": ":Company",
|
||||||
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
|
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-03-28 10:35:31",
|
"creation": "2013-03-28 10:35:31",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
|
<<<<<<< HEAD:erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt
|
||||||
"modified": "2013-12-20 16:06:50",
|
"modified": "2013-12-20 16:06:50",
|
||||||
|
=======
|
||||||
|
"modified": "2014-01-15 15:45:07",
|
||||||
|
>>>>>>> dbb495548352d46b30bf84fb4b29ef4a247cb21c:stock/doctype/stock_reconciliation/stock_reconciliation.txt
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -101,7 +105,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
|
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "expense_account",
|
"fieldname": "expense_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@ -109,6 +113,7 @@
|
|||||||
"options": "Account"
|
"options": "Account"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
@ -15,7 +15,7 @@ def execute(filters=None):
|
|||||||
bom_rate = get_item_bom_rate()
|
bom_rate = get_item_bom_rate()
|
||||||
val_rate_map = get_valuation_rate()
|
val_rate_map = get_valuation_rate()
|
||||||
|
|
||||||
precision = get_currency_precision or 2
|
precision = get_currency_precision() or 2
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for item in sorted(item_map):
|
for item in sorted(item_map):
|
||||||
@ -65,13 +65,13 @@ def get_price_list():
|
|||||||
|
|
||||||
rate = {}
|
rate = {}
|
||||||
|
|
||||||
price_list = webnotes.conn.sql("""select item_code, buying_or_selling,
|
price_list = webnotes.conn.sql("""select item_code, buying, selling,
|
||||||
concat(price_list, " - ", currency, " ", ref_rate) as price
|
concat(price_list, " - ", currency, " ", ref_rate) as price
|
||||||
from `tabItem Price`""", as_dict=1)
|
from `tabItem Price`""", as_dict=1)
|
||||||
|
|
||||||
for j in price_list:
|
for j in price_list:
|
||||||
if j.price:
|
if j.price:
|
||||||
rate.setdefault(j.item_code, {}).setdefault(j.buying_or_selling, []).append(j.price)
|
rate.setdefault(j.item_code, {}).setdefault("Buying" if j.buying else "Selling", []).append(j.price)
|
||||||
item_rate_map = {}
|
item_rate_map = {}
|
||||||
|
|
||||||
for item in rate:
|
for item in rate:
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-09-25 10:21:15",
|
"creation": "2013-09-25 10:21:15",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-10-21 16:06:22",
|
"modified": "2014-01-07 18:35:22",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"json": "{\"filters\":[[\"Item Price\",\"price_list\",\"like\",\"%\"],[\"Item Price\",\"item_code\",\"like\",\"%\"]],\"columns\":[[\"name\",\"Item Price\"],[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Item Price\"],[\"currency\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
"json": "{\"filters\":[[\"Item Price\",\"price_list\",\"like\",\"%\"],[\"Item Price\",\"item_code\",\"like\",\"%\"]],\"columns\":[[\"name\",\"Item Price\"],[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"ref_rate\",\"Item Price\"],[\"buying\",\"Item Price\"],[\"selling\",\"Item Price\"],[\"currency\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"ref_doctype": "Price List",
|
"ref_doctype": "Price List",
|
||||||
"report_name": "Item-wise Price List Rate",
|
"report_name": "Item-wise Price List Rate",
|
@ -2,11 +2,12 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-01-10 16:34:30",
|
"creation": "2013-01-10 16:34:30",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-12-20 19:24:02",
|
"modified": "2014-01-14 15:56:22",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "harshada@webnotestech.com"
|
"owner": "harshada@webnotestech.com"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"icon": "icon-bug",
|
"icon": "icon-bug",
|
||||||
|
@ -52,11 +52,6 @@ Original Query:
|
|||||||
subject = '['+cstr(d.name)+'] ' + cstr(d.subject), \
|
subject = '['+cstr(d.name)+'] ' + cstr(d.subject), \
|
||||||
msg = cstr(response))
|
msg = cstr(response))
|
||||||
|
|
||||||
def auto_close_tickets(self):
|
|
||||||
webnotes.conn.sql("""update `tabSupport Ticket` set status = 'Closed'
|
|
||||||
where status = 'Replied'
|
|
||||||
and date_sub(curdate(),interval 15 Day) > modified""")
|
|
||||||
|
|
||||||
def get_support_mails():
|
def get_support_mails():
|
||||||
if cint(webnotes.conn.get_value('Email Settings', None, 'sync_support_mails')):
|
if cint(webnotes.conn.get_value('Email Settings', None, 'sync_support_mails')):
|
||||||
SupportMailbox()
|
SupportMailbox()
|
||||||
|
@ -67,3 +67,8 @@ def set_status(name, status):
|
|||||||
st = webnotes.bean("Support Ticket", name)
|
st = webnotes.bean("Support Ticket", name)
|
||||||
st.doc.status = status
|
st.doc.status = status
|
||||||
st.save()
|
st.save()
|
||||||
|
|
||||||
|
def auto_close_tickets():
|
||||||
|
webnotes.conn.sql("""update `tabSupport Ticket` set status = 'Closed'
|
||||||
|
where status = 'Replied'
|
||||||
|
and date_sub(curdate(),interval 15 Day) > modified""")
|
||||||
|
@ -79,9 +79,11 @@ class TransactionBase(StatusUpdater):
|
|||||||
"""
|
"""
|
||||||
customer_defaults = self.get_customer_defaults()
|
customer_defaults = self.get_customer_defaults()
|
||||||
|
|
||||||
customer_defaults["selling_price_list"] = customer_defaults.get("price_list") or \
|
customer_defaults["selling_price_list"] = \
|
||||||
webnotes.conn.get_value("Customer Group", self.doc.customer_group, "default_price_list") or \
|
self.get_user_default_price_list("selling_price_list") or \
|
||||||
self.doc.selling_price_list
|
customer_defaults.get("price_list") or \
|
||||||
|
webnotes.conn.get_value("Customer Group", self.doc.customer_group,
|
||||||
|
"default_price_list") or self.doc.selling_price_list
|
||||||
|
|
||||||
for fieldname, val in customer_defaults.items():
|
for fieldname, val in customer_defaults.items():
|
||||||
if self.meta.get_field(fieldname):
|
if self.meta.get_field(fieldname):
|
||||||
@ -90,6 +92,12 @@ class TransactionBase(StatusUpdater):
|
|||||||
if self.meta.get_field("sales_team") and self.doc.customer:
|
if self.meta.get_field("sales_team") and self.doc.customer:
|
||||||
self.set_sales_team_for_customer()
|
self.set_sales_team_for_customer()
|
||||||
|
|
||||||
|
def get_user_default_price_list(self, price_list):
|
||||||
|
from webnotes.defaults import get_defaults_for
|
||||||
|
user_default_price_list = get_defaults_for(webnotes.session.user).get(price_list)
|
||||||
|
return cstr(user_default_price_list) \
|
||||||
|
if not isinstance(user_default_price_list, list) else ""
|
||||||
|
|
||||||
def set_sales_team_for_customer(self):
|
def set_sales_team_for_customer(self):
|
||||||
from webnotes.model import default_fields
|
from webnotes.model import default_fields
|
||||||
|
|
||||||
@ -120,8 +128,9 @@ class TransactionBase(StatusUpdater):
|
|||||||
out["supplier_name"] = supplier.supplier_name
|
out["supplier_name"] = supplier.supplier_name
|
||||||
if supplier.default_currency:
|
if supplier.default_currency:
|
||||||
out["currency"] = supplier.default_currency
|
out["currency"] = supplier.default_currency
|
||||||
if supplier.default_price_list:
|
|
||||||
out["buying_price_list"] = supplier.default_price_list
|
out["buying_price_list"] = self.get_user_default_price_list("buying_price_list") or \
|
||||||
|
supplier.default_price_list or self.doc.buying_price_list
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import os, sys
|
import os, sys
|
||||||
import argparse
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
|
||||||
is_redhat = is_debian = None
|
is_redhat = is_debian = None
|
||||||
root_password = None
|
root_password = None
|
||||||
@ -80,7 +81,7 @@ def validate_install():
|
|||||||
return is_redhat, is_debian
|
return is_redhat, is_debian
|
||||||
|
|
||||||
def install_using_yum():
|
def install_using_yum():
|
||||||
packages = "python python-setuptools gcc python-devel MySQL-python git memcached ntp vim-enhanced screen"
|
packages = "gcc MySQL-python git memcached ntp vim-enhanced screen"
|
||||||
|
|
||||||
print "-"*80
|
print "-"*80
|
||||||
print "Installing Packages: (This may take some time)"
|
print "Installing Packages: (This may take some time)"
|
||||||
@ -88,7 +89,10 @@ def install_using_yum():
|
|||||||
print "-"*80
|
print "-"*80
|
||||||
exec_in_shell("yum install -y %s" % packages)
|
exec_in_shell("yum install -y %s" % packages)
|
||||||
|
|
||||||
if not exec_in_shell("which mysql"):
|
|
||||||
|
try:
|
||||||
|
exec_in_shell("which mysql")
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
packages = "mysql mysql-server mysql-devel"
|
packages = "mysql mysql-server mysql-devel"
|
||||||
print "Installing Packages:", packages
|
print "Installing Packages:", packages
|
||||||
exec_in_shell("yum install -y %s" % packages)
|
exec_in_shell("yum install -y %s" % packages)
|
||||||
@ -101,26 +105,19 @@ def install_using_yum():
|
|||||||
exec_in_shell('mysqladmin -u root password "%s"' % (root_password,))
|
exec_in_shell('mysqladmin -u root password "%s"' % (root_password,))
|
||||||
print "Root password set as", root_password
|
print "Root password set as", root_password
|
||||||
|
|
||||||
# install htop
|
|
||||||
if not exec_in_shell("which htop"):
|
|
||||||
try:
|
|
||||||
exec_in_shell("cd /tmp && rpm -i --force http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm && yum install -y htop")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
update_config_for_redhat()
|
update_config_for_redhat()
|
||||||
|
|
||||||
def update_config_for_redhat():
|
def update_config_for_redhat():
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# set to autostart on startup
|
# set to autostart on startup
|
||||||
for service in ("mysqld", "memcached", "ntpd"):
|
for service in ("mysqld", "memcached"):
|
||||||
exec_in_shell("chkconfig --level 2345 %s on" % service)
|
exec_in_shell("chkconfig --level 2345 %s on" % service)
|
||||||
exec_in_shell("service %s restart" % service)
|
exec_in_shell("service %s restart" % service)
|
||||||
|
|
||||||
def install_using_apt():
|
def install_using_apt():
|
||||||
exec_in_shell("apt-get update")
|
exec_in_shell("apt-get update")
|
||||||
packages = "python python-setuptools python-dev build-essential python-pip python-mysqldb git memcached ntp vim screen htop"
|
packages = "python python-setuptools python-dev build-essential python-mysqldb git memcached ntp vim screen htop"
|
||||||
print "-"*80
|
print "-"*80
|
||||||
print "Installing Packages: (This may take some time)"
|
print "Installing Packages: (This may take some time)"
|
||||||
print packages
|
print packages
|
||||||
@ -132,7 +129,9 @@ def install_using_apt():
|
|||||||
exec_in_shell("echo mysql-server mysql-server/root_password password %s | sudo debconf-set-selections" % root_password)
|
exec_in_shell("echo mysql-server mysql-server/root_password password %s | sudo debconf-set-selections" % root_password)
|
||||||
exec_in_shell("echo mysql-server mysql-server/root_password_again password %s | sudo debconf-set-selections" % root_password)
|
exec_in_shell("echo mysql-server mysql-server/root_password_again password %s | sudo debconf-set-selections" % root_password)
|
||||||
|
|
||||||
if not exec_in_shell("which mysql"):
|
try:
|
||||||
|
exec_in_shell("which mysql")
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
packages = "mysql-server libmysqlclient-dev"
|
packages = "mysql-server libmysqlclient-dev"
|
||||||
print "Installing Packages:", packages
|
print "Installing Packages:", packages
|
||||||
exec_in_shell("apt-get install -y %s" % packages)
|
exec_in_shell("apt-get install -y %s" % packages)
|
||||||
@ -140,7 +139,7 @@ def install_using_apt():
|
|||||||
update_config_for_debian()
|
update_config_for_debian()
|
||||||
|
|
||||||
def update_config_for_debian():
|
def update_config_for_debian():
|
||||||
for service in ("mysql", "ntpd"):
|
for service in ("mysql",):
|
||||||
exec_in_shell("service %s restart" % service)
|
exec_in_shell("service %s restart" % service)
|
||||||
|
|
||||||
def install_python_modules():
|
def install_python_modules():
|
||||||
@ -148,13 +147,14 @@ def install_python_modules():
|
|||||||
print "Installing Python Modules: (This may take some time)"
|
print "Installing Python Modules: (This may take some time)"
|
||||||
print "-"*80
|
print "-"*80
|
||||||
|
|
||||||
if not exec_in_shell("which pip"):
|
try:
|
||||||
exec_in_shell("easy_install pip")
|
exec_in_shell("which pip2.7")
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
exec_in_shell("easy_install-2.7 pip")
|
||||||
|
|
||||||
exec_in_shell("pip install --upgrade pip")
|
exec_in_shell("pip2.7 install --upgrade setuptools --no-use-wheel")
|
||||||
exec_in_shell("pip install --upgrade setuptools")
|
exec_in_shell("pip2.7 install --upgrade setuptools")
|
||||||
exec_in_shell("pip install --upgrade virtualenv")
|
exec_in_shell("pip2.7 install {}".format(' '.join(requirements)))
|
||||||
exec_in_shell("pip install {}".format(' '.join(requirements)))
|
|
||||||
|
|
||||||
def install_erpnext(install_path):
|
def install_erpnext(install_path):
|
||||||
print
|
print
|
||||||
@ -200,7 +200,7 @@ def setup_folders(install_path):
|
|||||||
app = os.path.join(install_path, "app")
|
app = os.path.join(install_path, "app")
|
||||||
if not os.path.exists(app):
|
if not os.path.exists(app):
|
||||||
print "Cloning erpnext"
|
print "Cloning erpnext"
|
||||||
exec_in_shell("cd %s && git clone https://github.com/webnotes/erpnext.git app" % install_path)
|
exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/erpnext.git app" % install_path)
|
||||||
exec_in_shell("cd app && git config core.filemode false")
|
exec_in_shell("cd app && git config core.filemode false")
|
||||||
if not os.path.exists(app):
|
if not os.path.exists(app):
|
||||||
raise Exception, "Couldn't clone erpnext repository"
|
raise Exception, "Couldn't clone erpnext repository"
|
||||||
@ -208,7 +208,7 @@ def setup_folders(install_path):
|
|||||||
lib = os.path.join(install_path, "lib")
|
lib = os.path.join(install_path, "lib")
|
||||||
if not os.path.exists(lib):
|
if not os.path.exists(lib):
|
||||||
print "Cloning wnframework"
|
print "Cloning wnframework"
|
||||||
exec_in_shell("cd %s && git clone https://github.com/webnotes/wnframework.git lib" % install_path)
|
exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/wnframework.git lib" % install_path)
|
||||||
exec_in_shell("cd lib && git config core.filemode false")
|
exec_in_shell("cd lib && git config core.filemode false")
|
||||||
if not os.path.exists(lib):
|
if not os.path.exists(lib):
|
||||||
raise Exception, "Couldn't clone wnframework repository"
|
raise Exception, "Couldn't clone wnframework repository"
|
||||||
@ -243,28 +243,8 @@ def post_install(install_path):
|
|||||||
|
|
||||||
def exec_in_shell(cmd):
|
def exec_in_shell(cmd):
|
||||||
# using Popen instead of os.system - as recommended by python docs
|
# using Popen instead of os.system - as recommended by python docs
|
||||||
from subprocess import Popen
|
import subprocess
|
||||||
import tempfile
|
out = subprocess.check_output(cmd, shell=True)
|
||||||
|
|
||||||
with tempfile.TemporaryFile() as stdout:
|
|
||||||
with tempfile.TemporaryFile() as stderr:
|
|
||||||
p = Popen(cmd, shell=True, stdout=stdout, stderr=stderr)
|
|
||||||
p.wait()
|
|
||||||
|
|
||||||
stdout.seek(0)
|
|
||||||
out = stdout.read()
|
|
||||||
if out: out = out.decode('utf-8')
|
|
||||||
|
|
||||||
stderr.seek(0)
|
|
||||||
err = stderr.read()
|
|
||||||
if err: err = err.decode('utf-8')
|
|
||||||
|
|
||||||
if err and any((kw in err.lower() for kw in ["traceback", "error", "exception"])):
|
|
||||||
print out
|
|
||||||
raise Exception, err
|
|
||||||
else:
|
|
||||||
print "."
|
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user