mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 00:44:45 +00:00
[fixes] for recurring and tests
This commit is contained in:
@@ -32,7 +32,7 @@ class Asset(Document):
|
|||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def validate_item(self):
|
def validate_item(self):
|
||||||
item = frappe.db.get_value("Item", self.item_code,
|
item = frappe.db.get_value("Item", self.item_code,
|
||||||
["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1)
|
["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1)
|
||||||
if not item:
|
if not item:
|
||||||
frappe.throw(_("Item {0} does not exist").format(self.item_code))
|
frappe.throw(_("Item {0} does not exist").format(self.item_code))
|
||||||
@@ -42,7 +42,7 @@ class Asset(Document):
|
|||||||
frappe.throw(_("Item {0} must be a Fixed Asset Item").format(self.item_code))
|
frappe.throw(_("Item {0} must be a Fixed Asset Item").format(self.item_code))
|
||||||
elif item.is_stock_item:
|
elif item.is_stock_item:
|
||||||
frappe.throw(_("Item {0} must be a non-stock item").format(self.item_code))
|
frappe.throw(_("Item {0} must be a non-stock item").format(self.item_code))
|
||||||
|
|
||||||
def set_missing_values(self):
|
def set_missing_values(self):
|
||||||
if self.item_code:
|
if self.item_code:
|
||||||
item_details = get_item_details(self.item_code)
|
item_details = get_item_details(self.item_code)
|
||||||
@@ -50,7 +50,7 @@ class Asset(Document):
|
|||||||
if not self.get(field):
|
if not self.get(field):
|
||||||
self.set(field, value)
|
self.set(field, value)
|
||||||
|
|
||||||
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
|
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
|
||||||
flt(self.opening_accumulated_depreciation))
|
flt(self.opening_accumulated_depreciation))
|
||||||
|
|
||||||
def validate_asset_values(self):
|
def validate_asset_values(self):
|
||||||
@@ -59,7 +59,7 @@ class Asset(Document):
|
|||||||
|
|
||||||
if not flt(self.gross_purchase_amount):
|
if not flt(self.gross_purchase_amount):
|
||||||
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
||||||
|
|
||||||
if not self.is_existing_asset:
|
if not self.is_existing_asset:
|
||||||
self.opening_accumulated_depreciation = 0
|
self.opening_accumulated_depreciation = 0
|
||||||
self.number_of_depreciations_booked = 0
|
self.number_of_depreciations_booked = 0
|
||||||
@@ -70,33 +70,33 @@ class Asset(Document):
|
|||||||
if flt(self.opening_accumulated_depreciation) > depreciable_amount:
|
if flt(self.opening_accumulated_depreciation) > depreciable_amount:
|
||||||
frappe.throw(_("Opening Accumulated Depreciation must be less than equal to {0}")
|
frappe.throw(_("Opening Accumulated Depreciation must be less than equal to {0}")
|
||||||
.format(depreciable_amount))
|
.format(depreciable_amount))
|
||||||
|
|
||||||
if self.opening_accumulated_depreciation:
|
if self.opening_accumulated_depreciation:
|
||||||
if not self.number_of_depreciations_booked:
|
if not self.number_of_depreciations_booked:
|
||||||
frappe.throw(_("Please set Number of Depreciations Booked"))
|
frappe.throw(_("Please set Number of Depreciations Booked"))
|
||||||
else:
|
else:
|
||||||
self.number_of_depreciations_booked = 0
|
self.number_of_depreciations_booked = 0
|
||||||
|
|
||||||
if cint(self.number_of_depreciations_booked) > cint(self.total_number_of_depreciations):
|
if cint(self.number_of_depreciations_booked) > cint(self.total_number_of_depreciations):
|
||||||
frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
|
frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
|
||||||
|
|
||||||
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(nowdate()):
|
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(nowdate()):
|
||||||
frappe.msgprint(_("Next Depreciation Date is entered as past date"), title=_('Warning'), indicator='red')
|
frappe.msgprint(_("Next Depreciation Date is entered as past date"), title=_('Warning'), indicator='red')
|
||||||
|
|
||||||
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(self.purchase_date):
|
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(self.purchase_date):
|
||||||
frappe.throw(_("Next Depreciation Date cannot be before Purchase Date"))
|
frappe.throw(_("Next Depreciation Date cannot be before Purchase Date"))
|
||||||
|
|
||||||
if (flt(self.value_after_depreciation) > flt(self.expected_value_after_useful_life)
|
if (flt(self.value_after_depreciation) > flt(self.expected_value_after_useful_life)
|
||||||
and not self.next_depreciation_date):
|
and not self.next_depreciation_date):
|
||||||
frappe.throw(_("Please set Next Depreciation Date"))
|
frappe.throw(_("Please set Next Depreciation Date"))
|
||||||
|
|
||||||
def make_depreciation_schedule(self):
|
def make_depreciation_schedule(self):
|
||||||
if self.depreciation_method != 'Manual':
|
if self.depreciation_method != 'Manual':
|
||||||
self.schedules = []
|
self.schedules = []
|
||||||
|
|
||||||
if not self.get("schedules") and self.next_depreciation_date:
|
if not self.get("schedules") and self.next_depreciation_date:
|
||||||
value_after_depreciation = flt(self.value_after_depreciation)
|
value_after_depreciation = flt(self.value_after_depreciation)
|
||||||
|
|
||||||
number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
|
number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
|
||||||
cint(self.number_of_depreciations_booked)
|
cint(self.number_of_depreciations_booked)
|
||||||
if number_of_pending_depreciations:
|
if number_of_pending_depreciations:
|
||||||
@@ -111,7 +111,7 @@ class Asset(Document):
|
|||||||
"schedule_date": schedule_date,
|
"schedule_date": schedule_date,
|
||||||
"depreciation_amount": depreciation_amount
|
"depreciation_amount": depreciation_amount
|
||||||
})
|
})
|
||||||
|
|
||||||
def set_accumulated_depreciation(self):
|
def set_accumulated_depreciation(self):
|
||||||
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
||||||
for d in self.get("schedules"):
|
for d in self.get("schedules"):
|
||||||
@@ -121,7 +121,7 @@ class Asset(Document):
|
|||||||
def get_depreciation_amount(self, depreciable_value):
|
def get_depreciation_amount(self, depreciable_value):
|
||||||
if self.depreciation_method in ("Straight Line", "Manual"):
|
if self.depreciation_method in ("Straight Line", "Manual"):
|
||||||
depreciation_amount = (flt(self.value_after_depreciation) -
|
depreciation_amount = (flt(self.value_after_depreciation) -
|
||||||
flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) -
|
flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) -
|
||||||
cint(self.number_of_depreciations_booked))
|
cint(self.number_of_depreciations_booked))
|
||||||
else:
|
else:
|
||||||
factor = 200.0 / self.total_number_of_depreciations
|
factor = 200.0 / self.total_number_of_depreciations
|
||||||
@@ -132,14 +132,14 @@ class Asset(Document):
|
|||||||
depreciation_amount = flt(depreciable_value) - flt(self.expected_value_after_useful_life)
|
depreciation_amount = flt(depreciable_value) - flt(self.expected_value_after_useful_life)
|
||||||
|
|
||||||
return depreciation_amount
|
return depreciation_amount
|
||||||
|
|
||||||
def validate_expected_value_after_useful_life(self):
|
def validate_expected_value_after_useful_life(self):
|
||||||
accumulated_depreciation_after_full_schedule = \
|
accumulated_depreciation_after_full_schedule = \
|
||||||
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
|
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
|
||||||
|
|
||||||
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
|
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
|
||||||
flt(accumulated_depreciation_after_full_schedule))
|
flt(accumulated_depreciation_after_full_schedule))
|
||||||
|
|
||||||
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
|
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
|
||||||
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")
|
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")
|
||||||
.format(asset_value_after_full_schedule))
|
.format(asset_value_after_full_schedule))
|
||||||
@@ -156,8 +156,8 @@ class Asset(Document):
|
|||||||
if d.journal_entry:
|
if d.journal_entry:
|
||||||
frappe.get_doc("Journal Entry", d.journal_entry).cancel()
|
frappe.get_doc("Journal Entry", d.journal_entry).cancel()
|
||||||
d.db_set("journal_entry", None)
|
d.db_set("journal_entry", None)
|
||||||
|
|
||||||
self.db_set("value_after_depreciation",
|
self.db_set("value_after_depreciation",
|
||||||
(flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)))
|
(flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)))
|
||||||
|
|
||||||
def set_status(self, status=None):
|
def set_status(self, status=None):
|
||||||
@@ -188,6 +188,7 @@ def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, post
|
|||||||
pi = frappe.new_doc("Purchase Invoice")
|
pi = frappe.new_doc("Purchase Invoice")
|
||||||
pi.company = company
|
pi.company = company
|
||||||
pi.currency = frappe.db.get_value("Company", company, "default_currency")
|
pi.currency = frappe.db.get_value("Company", company, "default_currency")
|
||||||
|
pi.set_posting_date = 1
|
||||||
pi.posting_date = posting_date
|
pi.posting_date = posting_date
|
||||||
pi.append("items", {
|
pi.append("items", {
|
||||||
"item_code": item_code,
|
"item_code": item_code,
|
||||||
@@ -200,7 +201,7 @@ def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, post
|
|||||||
})
|
})
|
||||||
pi.set_missing_values()
|
pi.set_missing_values()
|
||||||
return pi
|
return pi
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_sales_invoice(asset, item_code, company):
|
def make_sales_invoice(asset, item_code, company):
|
||||||
si = frappe.new_doc("Sales Invoice")
|
si = frappe.new_doc("Sales Invoice")
|
||||||
@@ -217,7 +218,7 @@ def make_sales_invoice(asset, item_code, company):
|
|||||||
})
|
})
|
||||||
si.set_missing_values()
|
si.set_missing_values()
|
||||||
return si
|
return si
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def transfer_asset(args):
|
def transfer_asset(args):
|
||||||
import json
|
import json
|
||||||
@@ -226,23 +227,23 @@ def transfer_asset(args):
|
|||||||
movement_entry.update(args)
|
movement_entry.update(args)
|
||||||
movement_entry.insert()
|
movement_entry.insert()
|
||||||
movement_entry.submit()
|
movement_entry.submit()
|
||||||
|
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
frappe.msgprint(_("Asset Movement record {0} created").format("<a href='#Form/Asset Movement/{0}'>{0}</a>".format(movement_entry.name)))
|
frappe.msgprint(_("Asset Movement record {0} created").format("<a href='#Form/Asset Movement/{0}'>{0}</a>".format(movement_entry.name)))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_item_details(item_code):
|
def get_item_details(item_code):
|
||||||
asset_category = frappe.db.get_value("Item", item_code, "asset_category")
|
asset_category = frappe.db.get_value("Item", item_code, "asset_category")
|
||||||
|
|
||||||
if not asset_category:
|
if not asset_category:
|
||||||
frappe.throw(_("Please enter Asset Category in Item {0}").format(item_code))
|
frappe.throw(_("Please enter Asset Category in Item {0}").format(item_code))
|
||||||
|
|
||||||
ret = frappe.db.get_value("Asset Category", asset_category,
|
ret = frappe.db.get_value("Asset Category", asset_category,
|
||||||
["depreciation_method", "total_number_of_depreciations", "frequency_of_depreciation"], as_dict=1)
|
["depreciation_method", "total_number_of_depreciations", "frequency_of_depreciation"], as_dict=1)
|
||||||
|
|
||||||
ret.update({
|
ret.update({
|
||||||
"asset_category": asset_category
|
"asset_category": asset_category
|
||||||
})
|
})
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
@@ -254,7 +255,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"default": "",
|
"default": "",
|
||||||
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)",
|
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.docstatus==0",
|
||||||
"fieldname": "party_type",
|
"fieldname": "party_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -1664,17 +1665,17 @@
|
|||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-02-17 16:15:52.917533",
|
"modified": "2017-03-14 17:12:48.816644",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@@ -1046,6 +1046,8 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
def create_sales_invoice(**args):
|
def create_sales_invoice(**args):
|
||||||
si = frappe.new_doc("Sales Invoice")
|
si = frappe.new_doc("Sales Invoice")
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
if si.posting_date:
|
||||||
|
si.set_posting_date = 1
|
||||||
si.posting_date = args.posting_date or nowdate()
|
si.posting_date = args.posting_date or nowdate()
|
||||||
|
|
||||||
si.company = args.company or "_Test Company"
|
si.company = args.company or "_Test Company"
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ def make_new_document(reference_doc, date_field, posting_date):
|
|||||||
"next_date": get_next_date(reference_doc.next_date, mcount,cint(reference_doc.repeat_on_day_of_month))
|
"next_date": get_next_date(reference_doc.next_date, mcount,cint(reference_doc.repeat_on_day_of_month))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if new_document.meta.get_field('set_posting_time'):
|
||||||
|
new_document.set('set_posting_time', 1)
|
||||||
|
|
||||||
# copy document fields
|
# copy document fields
|
||||||
for fieldname in ("owner", "recurring_type", "repeat_on_day_of_month",
|
for fieldname in ("owner", "recurring_type", "repeat_on_day_of_month",
|
||||||
"recurring_id", "notification_email_address", "is_recurring", "end_date",
|
"recurring_id", "notification_email_address", "is_recurring", "end_date",
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ class TestDeliveryNote(unittest.TestCase):
|
|||||||
|
|
||||||
def test_delivery_of_bundled_items_to_target_warehouse(self):
|
def test_delivery_of_bundled_items_to_target_warehouse(self):
|
||||||
set_perpetual_inventory()
|
set_perpetual_inventory()
|
||||||
|
|
||||||
set_valuation_method("_Test Item", "FIFO")
|
set_valuation_method("_Test Item", "FIFO")
|
||||||
set_valuation_method("_Test Item Home Desktop 100", "FIFO")
|
set_valuation_method("_Test Item Home Desktop 100", "FIFO")
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ class TestDeliveryNote(unittest.TestCase):
|
|||||||
qty=100, rate=100)
|
qty=100, rate=100)
|
||||||
create_stock_reconciliation(item_code="_Test Item Home Desktop 100",
|
create_stock_reconciliation(item_code="_Test Item Home Desktop 100",
|
||||||
target=warehouse, qty=100, rate=100)
|
target=warehouse, qty=100, rate=100)
|
||||||
|
|
||||||
opening_qty_test_warehouse_1 = get_qty_after_transaction(warehouse="_Test Warehouse 1 - _TC")
|
opening_qty_test_warehouse_1 = get_qty_after_transaction(warehouse="_Test Warehouse 1 - _TC")
|
||||||
|
|
||||||
dn = create_delivery_note(item_code="_Test Product Bundle Item",
|
dn = create_delivery_note(item_code="_Test Product Bundle Item",
|
||||||
@@ -354,28 +354,28 @@ class TestDeliveryNote(unittest.TestCase):
|
|||||||
|
|
||||||
# stock value diff for source warehouse
|
# stock value diff for source warehouse
|
||||||
# for "_Test Item"
|
# for "_Test Item"
|
||||||
stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
|
stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
|
||||||
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
||||||
"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"},
|
"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"},
|
||||||
"stock_value_difference")
|
"stock_value_difference")
|
||||||
|
|
||||||
# stock value diff for target warehouse
|
# stock value diff for target warehouse
|
||||||
stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry",
|
stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry",
|
||||||
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
||||||
"item_code": "_Test Item", "warehouse": "_Test Warehouse 1 - _TC"},
|
"item_code": "_Test Item", "warehouse": "_Test Warehouse 1 - _TC"},
|
||||||
"stock_value_difference")
|
"stock_value_difference")
|
||||||
|
|
||||||
self.assertEquals(abs(stock_value_difference), stock_value_difference1)
|
self.assertEquals(abs(stock_value_difference), stock_value_difference1)
|
||||||
|
|
||||||
# for "_Test Item Home Desktop 100"
|
# for "_Test Item Home Desktop 100"
|
||||||
stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
|
stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
|
||||||
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
||||||
"item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse - _TC"},
|
"item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse - _TC"},
|
||||||
"stock_value_difference")
|
"stock_value_difference")
|
||||||
|
|
||||||
# stock value diff for target warehouse
|
# stock value diff for target warehouse
|
||||||
stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry",
|
stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry",
|
||||||
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
{"voucher_type": "Delivery Note", "voucher_no": dn.name,
|
||||||
"item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse 1 - _TC"},
|
"item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse 1 - _TC"},
|
||||||
"stock_value_difference")
|
"stock_value_difference")
|
||||||
|
|
||||||
@@ -397,118 +397,120 @@ class TestDeliveryNote(unittest.TestCase):
|
|||||||
self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account))
|
self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account))
|
||||||
|
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
def test_closed_delivery_note(self):
|
def test_closed_delivery_note(self):
|
||||||
from erpnext.stock.doctype.delivery_note.delivery_note import update_delivery_note_status
|
from erpnext.stock.doctype.delivery_note.delivery_note import update_delivery_note_status
|
||||||
|
|
||||||
dn = create_delivery_note(do_not_submit=True)
|
dn = create_delivery_note(do_not_submit=True)
|
||||||
dn.submit()
|
dn.submit()
|
||||||
|
|
||||||
update_delivery_note_status(dn.name, "Closed")
|
update_delivery_note_status(dn.name, "Closed")
|
||||||
self.assertEquals(frappe.db.get_value("Delivery Note", dn.name, "Status"), "Closed")
|
self.assertEquals(frappe.db.get_value("Delivery Note", dn.name, "Status"), "Closed")
|
||||||
|
|
||||||
def test_dn_billing_status_case1(self):
|
def test_dn_billing_status_case1(self):
|
||||||
# SO -> DN -> SI
|
# SO -> DN -> SI
|
||||||
so = make_sales_order()
|
so = make_sales_order()
|
||||||
dn = create_dn_against_so(so.name, delivered_qty=2)
|
dn = create_dn_against_so(so.name, delivered_qty=2)
|
||||||
|
|
||||||
self.assertEqual(dn.status, "To Bill")
|
self.assertEqual(dn.status, "To Bill")
|
||||||
self.assertEqual(dn.per_billed, 0)
|
self.assertEqual(dn.per_billed, 0)
|
||||||
|
|
||||||
si = make_sales_invoice(dn.name)
|
si = make_sales_invoice(dn.name)
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
dn.load_from_db()
|
dn.load_from_db()
|
||||||
self.assertEqual(dn.get("items")[0].billed_amt, 200)
|
self.assertEqual(dn.get("items")[0].billed_amt, 200)
|
||||||
self.assertEqual(dn.per_billed, 100)
|
self.assertEqual(dn.per_billed, 100)
|
||||||
self.assertEqual(dn.status, "Completed")
|
self.assertEqual(dn.status, "Completed")
|
||||||
|
|
||||||
def test_dn_billing_status_case2(self):
|
def test_dn_billing_status_case2(self):
|
||||||
# SO -> SI and SO -> DN1, DN2
|
# SO -> SI and SO -> DN1, DN2
|
||||||
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice
|
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice
|
||||||
|
|
||||||
so = make_sales_order()
|
so = make_sales_order()
|
||||||
|
|
||||||
si = make_sales_invoice(so.name)
|
si = make_sales_invoice(so.name)
|
||||||
si.get("items")[0].qty = 5
|
si.get("items")[0].qty = 5
|
||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
|
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
|
||||||
|
|
||||||
dn1 = make_delivery_note(so.name)
|
dn1 = make_delivery_note(so.name)
|
||||||
|
dn1.set_posting_time = 1
|
||||||
dn1.posting_time = "10:00"
|
dn1.posting_time = "10:00"
|
||||||
dn1.get("items")[0].qty = 2
|
dn1.get("items")[0].qty = 2
|
||||||
dn1.submit()
|
dn1.submit()
|
||||||
|
|
||||||
self.assertEqual(dn1.get("items")[0].billed_amt, 200)
|
self.assertEqual(dn1.get("items")[0].billed_amt, 200)
|
||||||
self.assertEqual(dn1.per_billed, 100)
|
self.assertEqual(dn1.per_billed, 100)
|
||||||
self.assertEqual(dn1.status, "Completed")
|
self.assertEqual(dn1.status, "Completed")
|
||||||
|
|
||||||
dn2 = make_delivery_note(so.name)
|
dn2 = make_delivery_note(so.name)
|
||||||
dn2.posting_time = "08:00"
|
dn2.posting_time = "08:00"
|
||||||
dn2.get("items")[0].qty = 4
|
dn2.get("items")[0].qty = 4
|
||||||
dn2.submit()
|
dn2.submit()
|
||||||
|
|
||||||
dn1.load_from_db()
|
dn1.load_from_db()
|
||||||
self.assertEqual(dn1.get("items")[0].billed_amt, 100)
|
self.assertEqual(dn1.get("items")[0].billed_amt, 100)
|
||||||
self.assertEqual(dn1.per_billed, 50)
|
self.assertEqual(dn1.per_billed, 50)
|
||||||
self.assertEqual(dn1.status, "To Bill")
|
self.assertEqual(dn1.status, "To Bill")
|
||||||
|
|
||||||
self.assertEqual(dn2.get("items")[0].billed_amt, 400)
|
self.assertEqual(dn2.get("items")[0].billed_amt, 400)
|
||||||
self.assertEqual(dn2.per_billed, 100)
|
self.assertEqual(dn2.per_billed, 100)
|
||||||
self.assertEqual(dn2.status, "Completed")
|
self.assertEqual(dn2.status, "Completed")
|
||||||
|
|
||||||
def test_dn_billing_status_case3(self):
|
def test_dn_billing_status_case3(self):
|
||||||
# SO -> DN1 -> SI and SO -> SI and SO -> DN2
|
# SO -> DN1 -> SI and SO -> SI and SO -> DN2
|
||||||
from erpnext.selling.doctype.sales_order.sales_order \
|
from erpnext.selling.doctype.sales_order.sales_order \
|
||||||
import make_delivery_note, make_sales_invoice as make_sales_invoice_from_so
|
import make_delivery_note, make_sales_invoice as make_sales_invoice_from_so
|
||||||
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
|
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
|
||||||
|
|
||||||
so = make_sales_order()
|
so = make_sales_order()
|
||||||
|
|
||||||
dn1 = make_delivery_note(so.name)
|
dn1 = make_delivery_note(so.name)
|
||||||
|
dn1.set_posting_time = 1
|
||||||
dn1.posting_time = "10:00"
|
dn1.posting_time = "10:00"
|
||||||
dn1.get("items")[0].qty = 2
|
dn1.get("items")[0].qty = 2
|
||||||
dn1.submit()
|
dn1.submit()
|
||||||
|
|
||||||
si1 = make_sales_invoice(dn1.name)
|
si1 = make_sales_invoice(dn1.name)
|
||||||
si1.submit()
|
si1.submit()
|
||||||
|
|
||||||
dn1.load_from_db()
|
dn1.load_from_db()
|
||||||
self.assertEqual(dn1.per_billed, 100)
|
self.assertEqual(dn1.per_billed, 100)
|
||||||
|
|
||||||
si2 = make_sales_invoice_from_so(so.name)
|
si2 = make_sales_invoice_from_so(so.name)
|
||||||
si2.get("items")[0].qty = 4
|
si2.get("items")[0].qty = 4
|
||||||
si2.submit()
|
si2.submit()
|
||||||
|
|
||||||
dn2 = make_delivery_note(so.name)
|
dn2 = make_delivery_note(so.name)
|
||||||
dn2.posting_time = "08:00"
|
dn2.posting_time = "08:00"
|
||||||
dn2.get("items")[0].qty = 5
|
dn2.get("items")[0].qty = 5
|
||||||
dn2.submit()
|
dn2.submit()
|
||||||
|
|
||||||
dn1.load_from_db()
|
dn1.load_from_db()
|
||||||
self.assertEqual(dn1.get("items")[0].billed_amt, 200)
|
self.assertEqual(dn1.get("items")[0].billed_amt, 200)
|
||||||
self.assertEqual(dn1.per_billed, 100)
|
self.assertEqual(dn1.per_billed, 100)
|
||||||
self.assertEqual(dn1.status, "Completed")
|
self.assertEqual(dn1.status, "Completed")
|
||||||
|
|
||||||
self.assertEqual(dn2.get("items")[0].billed_amt, 400)
|
self.assertEqual(dn2.get("items")[0].billed_amt, 400)
|
||||||
self.assertEqual(dn2.per_billed, 80)
|
self.assertEqual(dn2.per_billed, 80)
|
||||||
self.assertEqual(dn2.status, "To Bill")
|
self.assertEqual(dn2.status, "To Bill")
|
||||||
|
|
||||||
def test_dn_billing_status_case4(self):
|
def test_dn_billing_status_case4(self):
|
||||||
# SO -> SI -> DN
|
# SO -> SI -> DN
|
||||||
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_delivery_note
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_delivery_note
|
||||||
|
|
||||||
so = make_sales_order()
|
so = make_sales_order()
|
||||||
|
|
||||||
si = make_sales_invoice(so.name)
|
si = make_sales_invoice(so.name)
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
dn = make_delivery_note(si.name)
|
dn = make_delivery_note(si.name)
|
||||||
dn.submit()
|
dn.submit()
|
||||||
|
|
||||||
self.assertEqual(dn.get("items")[0].billed_amt, 1000)
|
self.assertEqual(dn.get("items")[0].billed_amt, 1000)
|
||||||
self.assertEqual(dn.per_billed, 100)
|
self.assertEqual(dn.per_billed, 100)
|
||||||
self.assertEqual(dn.status, "Completed")
|
self.assertEqual(dn.status, "Completed")
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
|
|
||||||
def test_auto_material_request_for_variant(self):
|
def test_auto_material_request_for_variant(self):
|
||||||
self._test_auto_material_request("_Test Variant Item-S")
|
self._test_auto_material_request("_Test Variant Item-S")
|
||||||
|
|
||||||
def test_auto_material_request_for_warehouse_group(self):
|
def test_auto_material_request_for_warehouse_group(self):
|
||||||
self._test_auto_material_request("_Test Item Warehouse Group Wise Reorder", warehouse="_Test Warehouse Group-C1 - _TC")
|
self._test_auto_material_request("_Test Item Warehouse Group Wise Reorder", warehouse="_Test Warehouse Group-C1 - _TC")
|
||||||
|
|
||||||
def _test_auto_material_request(self, item_code, material_request_type="Purchase", warehouse="_Test Warehouse - _TC"):
|
def _test_auto_material_request(self, item_code, material_request_type="Purchase", warehouse="_Test Warehouse - _TC"):
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", item_code)
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
|
|
||||||
mr = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
mr = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
||||||
qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC")
|
qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC")
|
||||||
|
|
||||||
stock_in_hand_account = frappe.db.get_value("Account", {"account_type": "Stock",
|
stock_in_hand_account = frappe.db.get_value("Account", {"account_type": "Stock",
|
||||||
"warehouse": mr.get("items")[0].t_warehouse})
|
"warehouse": mr.get("items")[0].t_warehouse})
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
||||||
qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC")
|
qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC")
|
||||||
|
|
||||||
mi = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
mi = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
||||||
qty=40, expense_account="Stock Adjustment - _TC")
|
qty=40, expense_account="Stock Adjustment - _TC")
|
||||||
|
|
||||||
self.check_stock_ledger_entries("Stock Entry", mi.name,
|
self.check_stock_ledger_entries("Stock Entry", mi.name,
|
||||||
@@ -512,6 +512,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
# test freeze_stocks_upto_days
|
# test freeze_stocks_upto_days
|
||||||
frappe.db.set_value("Stock Settings", None, "stock_frozen_upto_days", 7)
|
frappe.db.set_value("Stock Settings", None, "stock_frozen_upto_days", 7)
|
||||||
se = frappe.copy_doc(test_records[0])
|
se = frappe.copy_doc(test_records[0])
|
||||||
|
se.set_posting_time = 1
|
||||||
se.posting_date = add_days(nowdate(), -15)
|
se.posting_date = add_days(nowdate(), -15)
|
||||||
se.insert()
|
se.insert()
|
||||||
self.assertRaises(StockFreezeError, se.submit)
|
self.assertRaises(StockFreezeError, se.submit)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class TestStockReconciliation(unittest.TestCase):
|
|||||||
|
|
||||||
for d in input_data:
|
for d in input_data:
|
||||||
set_valuation_method("_Test Item", valuation_method)
|
set_valuation_method("_Test Item", valuation_method)
|
||||||
|
|
||||||
last_sle = get_previous_sle({
|
last_sle = get_previous_sle({
|
||||||
"item_code": "_Test Item",
|
"item_code": "_Test Item",
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
@@ -96,6 +96,7 @@ def create_stock_reconciliation(**args):
|
|||||||
sr = frappe.new_doc("Stock Reconciliation")
|
sr = frappe.new_doc("Stock Reconciliation")
|
||||||
sr.posting_date = args.posting_date or nowdate()
|
sr.posting_date = args.posting_date or nowdate()
|
||||||
sr.posting_time = args.posting_time or nowtime()
|
sr.posting_time = args.posting_time or nowtime()
|
||||||
|
sr.set_posting_time = 1
|
||||||
sr.company = args.company or "_Test Company"
|
sr.company = args.company or "_Test Company"
|
||||||
sr.expense_account = args.expense_account or \
|
sr.expense_account = args.expense_account or \
|
||||||
("Stock Adjustment - _TC" if frappe.get_all("Stock Ledger Entry") else "Temporary Opening - _TC")
|
("Stock Adjustment - _TC" if frappe.get_all("Stock Ledger Entry") else "Temporary Opening - _TC")
|
||||||
|
|||||||
Reference in New Issue
Block a user