mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-30 06:18:38 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b4b31fdf7 | ||
|
|
ec25117ab0 | ||
|
|
dfa013e73f | ||
|
|
f2791f8898 | ||
|
|
66773229a4 | ||
|
|
ead48094b6 | ||
|
|
d6822ddd7c | ||
|
|
4944fb33ce | ||
|
|
845f1c636e | ||
|
|
98dbccd1d6 | ||
|
|
7346ff3d08 | ||
|
|
21761c204c | ||
|
|
87f3ba139e | ||
|
|
11498cac94 | ||
|
|
7a31f6aaca | ||
|
|
7d5a2390dd | ||
|
|
081c3ec476 | ||
|
|
e2f054cc27 |
@@ -1,2 +1,2 @@
|
||||
from __future__ import unicode_literals
|
||||
__version__ = '4.23.0'
|
||||
__version__ = '4.24.1'
|
||||
|
||||
@@ -18,17 +18,17 @@ class CForm(Document):
|
||||
`tabSales Invoice` where name = %s and docstatus = 1""", d.invoice_no)
|
||||
|
||||
if inv and inv[0][0] != 'Yes':
|
||||
frappe.throw("C-form is not applicable for Invoice: %s" % d.invoice_no)
|
||||
frappe.throw("C-form is not applicable for Invoice: {0}".format(d.invoice_no))
|
||||
|
||||
elif inv and inv[0][1] and inv[0][1] != self.name:
|
||||
frappe.throw("""Invoice %s is tagged in another C-form: %s.
|
||||
frappe.throw("""Invoice {0} is tagged in another C-form: {1}.
|
||||
If you want to change C-form no for this invoice,
|
||||
please remove invoice no from the previous c-form and then try again""" %
|
||||
(d.invoice_no, inv[0][1]))
|
||||
please remove invoice no from the previous c-form and then try again"""\
|
||||
.format(d.invoice_no, inv[0][1]))
|
||||
|
||||
elif not inv:
|
||||
frappe.throw("Row %s: Invoice %s is invalid, it might be cancelled / does not exist. \
|
||||
Please enter a valid Invoice" % d.idx, d.invoice_no)
|
||||
frappe.throw("Row {0}: Invoice {1} is invalid, it might be cancelled / does not exist. \
|
||||
Please enter a valid Invoice".format(d.idx, d.invoice_no))
|
||||
|
||||
def on_update(self):
|
||||
""" Update C-Form No on invoices"""
|
||||
|
||||
@@ -244,7 +244,7 @@ cur_frm.cscript.hide_fields = function(doc) {
|
||||
cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_normal, true);
|
||||
}
|
||||
|
||||
item_flds_stock = ['serial_no', 'batch_no', 'actual_qty', 'expense_account', 'warehouse']
|
||||
item_flds_stock = ['serial_no', 'batch_no', 'actual_qty', 'actual_batch_qty', 'expense_account', 'warehouse']
|
||||
cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_stock,
|
||||
(cint(doc.update_stock)==1 ? true : false));
|
||||
|
||||
|
||||
@@ -339,6 +339,19 @@
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "actual_batch_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Available Batch Qty at Warehouse",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"width": "150px"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "actual_qty",
|
||||
@@ -439,7 +452,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-09-09 05:35:36.019576",
|
||||
"modified": "2015-03-10 14:56:45.641026",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
||||
@@ -112,6 +112,8 @@ class AccountsController(TransactionBase):
|
||||
if item.get("item_code"):
|
||||
args = parent_dict.copy()
|
||||
args.update(item.as_dict())
|
||||
if not args.get("transaction_date"):
|
||||
args["transaction_date"] = args.get("posting_date")
|
||||
ret = get_item_details(args)
|
||||
|
||||
for fieldname, value in ret.items():
|
||||
@@ -183,6 +185,7 @@ class AccountsController(TransactionBase):
|
||||
|
||||
self.calculate_net_total()
|
||||
self.calculate_taxes()
|
||||
self.manipulate_grand_total_for_inclusive_tax()
|
||||
self.calculate_totals()
|
||||
self._cleanup()
|
||||
|
||||
@@ -351,6 +354,22 @@ class AccountsController(TransactionBase):
|
||||
self.precision(base_field, item))
|
||||
item.set(base_field, value_in_company_currency)
|
||||
|
||||
def manipulate_grand_total_for_inclusive_tax(self):
|
||||
# if fully inclusive taxes and diff
|
||||
if (self.meta.get_field("net_total_export") and self.tax_doclist
|
||||
and all(cint(t.included_in_print_rate) for t in self.tax_doclist)):
|
||||
|
||||
last_tax = self.tax_doclist[-1]
|
||||
|
||||
diff = self.net_total_export - flt(last_tax.total / self.conversion_rate,
|
||||
self.precision("grand_total_export"))
|
||||
|
||||
if diff and abs(diff) <= (2.0 / 10**(self.precision("tax_amount", last_tax))):
|
||||
adjustment_amount = flt(diff * self.conversion_rate, self.precision("tax_amount", last_tax))
|
||||
last_tax.tax_amount += adjustment_amount
|
||||
last_tax.tax_amount_after_discount_amount += adjustment_amount
|
||||
last_tax.total += adjustment_amount
|
||||
|
||||
def calculate_total_advance(self, parenttype, advance_parentfield):
|
||||
if self.doctype == parenttype and self.docstatus < 2:
|
||||
sum_of_allocated_amount = sum([flt(adv.allocated_amount, self.precision("allocated_amount", adv))
|
||||
|
||||
@@ -5,7 +5,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors"
|
||||
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
|
||||
app_icon = "icon-th"
|
||||
app_color = "#e74c3c"
|
||||
app_version = "4.23.0"
|
||||
app_version = "4.24.1"
|
||||
|
||||
error_report_email = "support@erpnext.com"
|
||||
|
||||
|
||||
@@ -94,3 +94,5 @@ erpnext.patches.v4_2.discount_amount
|
||||
erpnext.patches.v4_2.update_landed_cost_voucher
|
||||
erpnext.patches.v4_2.set_item_has_batch
|
||||
erpnext.patches.v4_2.update_stock_uom_for_dn_in_sle
|
||||
erpnext.patches.v4_2.repost_reserved_qty
|
||||
erpnext.patches.v4_2.repost_sle_for_si_with_no_warehouse
|
||||
12
erpnext/patches/v4_2/repost_reserved_qty.py
Normal file
12
erpnext/patches/v4_2/repost_reserved_qty.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from erpnext.utilities.repost_stock import update_bin_qty, get_reserved_qty
|
||||
|
||||
def execute():
|
||||
for item_code, warehouse in frappe.db.sql("select item_code, warehouse from tabBin where ifnull(reserved_qty, 0) < 0"):
|
||||
update_bin_qty(item_code, warehouse, {
|
||||
"reserved_qty": get_reserved_qty(item_code, warehouse)
|
||||
})
|
||||
34
erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
Normal file
34
erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from erpnext.stock.stock_ledger import NegativeStockError
|
||||
|
||||
def execute():
|
||||
si_list = frappe.db.sql("""select distinct si.name
|
||||
from `tabSales Invoice Item` si_item, `tabSales Invoice` si
|
||||
where si.name = si_item.parent and si.modified > '2015-02-16' and si.docstatus=1
|
||||
and ifnull(si_item.warehouse, '') = '' and ifnull(si.update_stock, 0) = 1
|
||||
order by posting_date, posting_time""", as_dict=1)
|
||||
|
||||
failed_list = []
|
||||
for si in si_list:
|
||||
try:
|
||||
si_doc = frappe.get_doc("Sales Invoice", si.name)
|
||||
si_doc.docstatus = 2
|
||||
si_doc.on_cancel()
|
||||
|
||||
si_doc.docstatus = 1
|
||||
si_doc.set_missing_item_details()
|
||||
si_doc.on_submit()
|
||||
frappe.db.commit()
|
||||
except:
|
||||
failed_list.append(si.name)
|
||||
frappe.local.stockledger_exceptions = None
|
||||
frappe.db.rollback()
|
||||
|
||||
print "Failed to repost: ", failed_list
|
||||
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
order_type: me.frm.doc.order_type,
|
||||
is_pos: cint(me.frm.doc.is_pos),
|
||||
is_subcontracted: me.frm.doc.is_subcontracted,
|
||||
transaction_date: me.frm.doc.transaction_date,
|
||||
transaction_date: me.frm.doc.transaction_date || me.frm.doc.posting_date,
|
||||
ignore_pricing_rule: me.frm.doc.ignore_pricing_rule,
|
||||
doctype: item.doctype,
|
||||
name: item.name,
|
||||
@@ -632,6 +632,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
this.determine_exclusive_rate && this.determine_exclusive_rate();
|
||||
this.calculate_net_total();
|
||||
this.calculate_taxes();
|
||||
this.manipulate_grand_total_for_inclusive_tax && this.manipulate_grand_total_for_inclusive_tax();
|
||||
this.calculate_totals();
|
||||
this._cleanup();
|
||||
|
||||
|
||||
@@ -215,6 +215,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
},
|
||||
|
||||
warehouse: function(doc, cdt, cdn) {
|
||||
var me = this;
|
||||
this.batch_no(doc, cdt, cdn);
|
||||
var item = frappe.get_doc(cdt, cdn);
|
||||
if(item.item_code && item.warehouse) {
|
||||
return this.frm.call({
|
||||
@@ -456,6 +458,29 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
});
|
||||
},
|
||||
|
||||
manipulate_grand_total_for_inclusive_tax: function() {
|
||||
// if fully inclusive taxes and diff
|
||||
if (this.frm.tax_doclist.length) {
|
||||
var all_inclusive = frappe.utils.all(this.frm.tax_doclist.map(function(d) {
|
||||
return cint(d.included_in_print_rate);
|
||||
}));
|
||||
|
||||
if (all_inclusive) {
|
||||
var last_tax = this.frm.tax_doclist.slice(-1)[0];
|
||||
|
||||
var diff = this.frm.doc.net_total_export
|
||||
- flt(last_tax.total / this.frm.doc.conversion_rate, precision("grand_total_export"));
|
||||
|
||||
if ( diff && Math.abs(diff) <= (2.0 / Math.pow(10, precision("tax_amount", last_tax))) ) {
|
||||
var adjustment_amount = flt(diff * this.frm.doc.conversion_rate, precision("tax_amount", last_tax));
|
||||
last_tax.tax_amount += adjustment_amount;
|
||||
last_tax.tax_amount_after_discount += adjustment_amount;
|
||||
last_tax.total += adjustment_amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_cleanup: function() {
|
||||
this._super();
|
||||
this.frm.doc.in_words = this.frm.doc.in_words_export = "";
|
||||
@@ -476,6 +501,21 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
}
|
||||
},
|
||||
|
||||
batch_no: function(doc, cdt, cdn) {
|
||||
var me = this;
|
||||
var item = frappe.get_doc(cdt, cdn);
|
||||
return this.frm.call({
|
||||
method: "erpnext.stock.get_item_details.get_batch_qty",
|
||||
child: item,
|
||||
args: {
|
||||
"batch_no": item.batch_no,
|
||||
"warehouse": item.warehouse,
|
||||
"item_code": item.item_code
|
||||
},
|
||||
"fieldname": "actual_batch_qty"
|
||||
});
|
||||
},
|
||||
|
||||
set_dynamic_labels: function() {
|
||||
this._super();
|
||||
this.set_sales_bom_help(this.frm.doc);
|
||||
|
||||
@@ -314,6 +314,19 @@
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "actual_batch_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Available Batch Qty at Warehouse",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"width": "150px"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "actual_qty",
|
||||
@@ -426,7 +439,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-09-09 05:35:37.460939",
|
||||
"modified": "2015-03-10 12:21:17.028911",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note Item",
|
||||
|
||||
@@ -278,6 +278,15 @@ def get_serial_nos_by_fifo(args, item_doc):
|
||||
"qty": cint(args.qty)
|
||||
}))
|
||||
|
||||
def get_actual_batch_qty(batch_no,warehouse,item_code):
|
||||
actual_batch_qty = 0
|
||||
if batch_no:
|
||||
actual_batch_qty = flt(frappe.db.sql("""select sum(actual_qty)
|
||||
from `tabStock Ledger Entry`
|
||||
where warehouse=%s and item_code=%s and batch_no=%s""",
|
||||
(warehouse, item_code, batch_no))[0][0])
|
||||
return actual_batch_qty
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_conversion_factor(item_code, uom):
|
||||
return {"conversion_factor": frappe.db.get_value("UOM Conversion Detail",
|
||||
@@ -293,6 +302,12 @@ def get_available_qty(item_code, warehouse):
|
||||
return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
|
||||
["projected_qty", "actual_qty"], as_dict=True) or {}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_batch_qty(batch_no,warehouse,item_code):
|
||||
actual_batch_qty = get_actual_batch_qty(batch_no,warehouse,item_code)
|
||||
if batch_no:
|
||||
return {'actual_batch_qty': actual_batch_qty}
|
||||
|
||||
@frappe.whitelist()
|
||||
def apply_price_list(args):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user