mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 16:34:46 +00:00
Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS
This commit is contained in:
@@ -302,7 +302,7 @@ def get_invoice_vouchers(parties, tax_details, company, party_type="Supplier"):
|
|||||||
"docstatus": 1,
|
"docstatus": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
if not tax_details.get("consider_party_ledger_amount") and doctype != "Sales Invoice":
|
if doctype != "Sales Invoice":
|
||||||
filters.update(
|
filters.update(
|
||||||
{"apply_tds": 1, "tax_withholding_category": tax_details.get("tax_withholding_category")}
|
{"apply_tds": 1, "tax_withholding_category": tax_details.get("tax_withholding_category")}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -110,9 +110,9 @@ class TestTaxWithholdingCategory(unittest.TestCase):
|
|||||||
invoices.append(pi1)
|
invoices.append(pi1)
|
||||||
|
|
||||||
# Cumulative threshold is 30000
|
# Cumulative threshold is 30000
|
||||||
# Threshold calculation should be on both the invoices
|
# Threshold calculation should be only on the Second invoice
|
||||||
# TDS should be applied only on 1000
|
# Second didn't breach, no TDS should be applied
|
||||||
self.assertEqual(pi1.taxes[0].tax_amount, 1000)
|
self.assertEqual(pi1.taxes, [])
|
||||||
|
|
||||||
for d in reversed(invoices):
|
for d in reversed(invoices):
|
||||||
d.cancel()
|
d.cancel()
|
||||||
|
|||||||
@@ -691,7 +691,7 @@ class TestDepreciationMethods(AssetSetup):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(asset.status, "Draft")
|
self.assertEqual(asset.status, "Draft")
|
||||||
expected_schedules = [["2032-12-31", 30000.0, 77095.89], ["2033-06-06", 12904.11, 90000.0]]
|
expected_schedules = [["2032-12-31", 42904.11, 90000.0]]
|
||||||
schedules = [
|
schedules = [
|
||||||
[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
|
[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
|
||||||
for d in get_depr_schedule(asset.name, "Draft")
|
for d in get_depr_schedule(asset.name, "Draft")
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ class AssetDepreciationSchedule(Document):
|
|||||||
depreciation_amount += value_after_depreciation - row.expected_value_after_useful_life
|
depreciation_amount += value_after_depreciation - row.expected_value_after_useful_life
|
||||||
skip_row = True
|
skip_row = True
|
||||||
|
|
||||||
if depreciation_amount > 0:
|
if flt(depreciation_amount, asset_doc.precision("gross_purchase_amount")) > 0:
|
||||||
self.add_depr_schedule_row(
|
self.add_depr_schedule_row(
|
||||||
schedule_date,
|
schedule_date,
|
||||||
depreciation_amount,
|
depreciation_amount,
|
||||||
@@ -521,9 +521,11 @@ def get_straight_line_or_manual_depr_amount(asset, row):
|
|||||||
)
|
)
|
||||||
# if the Depreciation Schedule is being prepared for the first time
|
# if the Depreciation Schedule is being prepared for the first time
|
||||||
else:
|
else:
|
||||||
return (flt(asset.gross_purchase_amount) - flt(row.expected_value_after_useful_life)) / flt(
|
return (
|
||||||
row.total_number_of_depreciations
|
flt(asset.gross_purchase_amount)
|
||||||
)
|
- flt(asset.opening_accumulated_depreciation)
|
||||||
|
- flt(row.expected_value_after_useful_life)
|
||||||
|
) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
|
||||||
|
|
||||||
|
|
||||||
def get_wdv_or_dd_depr_amount(
|
def get_wdv_or_dd_depr_amount(
|
||||||
|
|||||||
@@ -7,4 +7,6 @@ def execute():
|
|||||||
frappe.reload_doc("manufacturing", "doctype", "work_order")
|
frappe.reload_doc("manufacturing", "doctype", "work_order")
|
||||||
frappe.reload_doc("manufacturing", "doctype", "work_order_item")
|
frappe.reload_doc("manufacturing", "doctype", "work_order_item")
|
||||||
|
|
||||||
frappe.db.sql("""UPDATE `tabWork Order Item` SET amount = rate * required_qty""")
|
frappe.db.sql(
|
||||||
|
"""UPDATE `tabWork Order Item` SET amount = ifnull(rate, 0.0) * ifnull(required_qty, 0.0)"""
|
||||||
|
)
|
||||||
|
|||||||
@@ -91,6 +91,12 @@ frappe.ui.form.on("Sales Invoice", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on('Purchase Invoice', {
|
frappe.ui.form.on('Purchase Invoice', {
|
||||||
|
setup: (frm) => {
|
||||||
|
frm.make_methods = {
|
||||||
|
'Landed Cost Voucher': function () { frm.trigger('create_landedcost_voucher') },
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
mode_of_payment: function(frm) {
|
mode_of_payment: function(frm) {
|
||||||
get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){
|
get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){
|
||||||
frm.set_value('cash_bank_account', account);
|
frm.set_value('cash_bank_account', account);
|
||||||
@@ -99,6 +105,20 @@ frappe.ui.form.on('Purchase Invoice', {
|
|||||||
|
|
||||||
payment_terms_template: function() {
|
payment_terms_template: function() {
|
||||||
cur_frm.trigger("disable_due_date");
|
cur_frm.trigger("disable_due_date");
|
||||||
|
},
|
||||||
|
|
||||||
|
create_landedcost_voucher: function (frm) {
|
||||||
|
let lcv = frappe.model.get_new_doc('Landed Cost Voucher');
|
||||||
|
lcv.company = frm.doc.company;
|
||||||
|
|
||||||
|
let lcv_receipt = frappe.model.get_new_doc('Landed Cost Purchase Invoice');
|
||||||
|
lcv_receipt.receipt_document_type = 'Purchase Invoice';
|
||||||
|
lcv_receipt.receipt_document = frm.doc.name;
|
||||||
|
lcv_receipt.supplier = frm.doc.supplier;
|
||||||
|
lcv_receipt.grand_total = frm.doc.grand_total;
|
||||||
|
lcv.purchase_receipts = [lcv_receipt];
|
||||||
|
|
||||||
|
frappe.set_route("Form", lcv.doctype, lcv.name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# sales team
|
# sales team
|
||||||
for d in customer.get("sales_team"):
|
for d in customer.get("sales_team") or []:
|
||||||
target.append(
|
target.append(
|
||||||
"sales_team",
|
"sales_team",
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class PickList(Document):
|
|||||||
self.validate_for_qty()
|
self.validate_for_qty()
|
||||||
|
|
||||||
def before_save(self):
|
def before_save(self):
|
||||||
|
self.update_status()
|
||||||
self.set_item_locations()
|
self.set_item_locations()
|
||||||
|
|
||||||
# set percentage picked in SO
|
# set percentage picked in SO
|
||||||
@@ -89,20 +90,20 @@ class PickList(Document):
|
|||||||
self.update_reference_qty()
|
self.update_reference_qty()
|
||||||
self.update_sales_order_picking_status()
|
self.update_sales_order_picking_status()
|
||||||
|
|
||||||
def update_status(self, status=None, update_modified=True):
|
def update_status(self, status=None):
|
||||||
if not status:
|
if not status:
|
||||||
if self.docstatus == 0:
|
if self.docstatus == 0:
|
||||||
status = "Draft"
|
status = "Draft"
|
||||||
elif self.docstatus == 1:
|
elif self.docstatus == 1:
|
||||||
if self.status == "Draft":
|
if target_document_exists(self.name, self.purpose):
|
||||||
status = "Open"
|
|
||||||
elif target_document_exists(self.name, self.purpose):
|
|
||||||
status = "Completed"
|
status = "Completed"
|
||||||
|
else:
|
||||||
|
status = "Open"
|
||||||
elif self.docstatus == 2:
|
elif self.docstatus == 2:
|
||||||
status = "Cancelled"
|
status = "Cancelled"
|
||||||
|
|
||||||
if status:
|
if status:
|
||||||
frappe.db.set_value("Pick List", self.name, "status", status, update_modified=update_modified)
|
self.db_set("status", status)
|
||||||
|
|
||||||
def update_reference_qty(self):
|
def update_reference_qty(self):
|
||||||
packed_items = []
|
packed_items = []
|
||||||
|
|||||||
@@ -76,26 +76,14 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let batch_no_field = frm.get_docfield("items", "batch_no");
|
let batch_no_field = frm.get_docfield('items', 'batch_no');
|
||||||
if (batch_no_field) {
|
if (batch_no_field) {
|
||||||
batch_no_field.get_route_options_for_new_doc = function(row) {
|
batch_no_field.get_route_options_for_new_doc = function(row) {
|
||||||
return {
|
return {
|
||||||
"item": row.doc.item_code
|
'item': row.doc.item_code
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => {
|
|
||||||
if (val == 'Material Transferred for Subcontract') {
|
|
||||||
frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => {
|
|
||||||
grid_row.docfields.forEach((df) => {
|
|
||||||
if (df.fieldname == 'consumed_qty') {
|
|
||||||
df.read_only = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: (frm) => {
|
refresh: (frm) => {
|
||||||
@@ -157,6 +145,8 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, __('Get Items From'));
|
}, __('Get Items From'));
|
||||||
|
|
||||||
|
frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty', 'read_only', frm.doc.__onload && frm.doc.__onload.backflush_based_on === 'BOM');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ class SubcontractingReceipt(SubcontractingController):
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def onload(self):
|
||||||
|
self.set_onload(
|
||||||
|
"backflush_based_on",
|
||||||
|
frappe.db.get_single_value(
|
||||||
|
"Buying Settings", "backflush_raw_materials_of_subcontract_based_on"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def update_status_updater_args(self):
|
def update_status_updater_args(self):
|
||||||
if cint(self.is_return):
|
if cint(self.is_return):
|
||||||
self.status_updater.extend(
|
self.status_updater.extend(
|
||||||
|
|||||||
Reference in New Issue
Block a user