def test_update_qty(self): so = make_sales_order() create_dn_against_so(so.name, 6) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 6) # Check delivered_qty after make_sales_invoice without update_stock checked si1 = make_sales_invoice(so.name) si1.get("items")[0].qty = 6 si1.insert() si1.submit() so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 6) # Check delivered_qty after make_sales_invoice with update_stock checked si2 = make_sales_invoice(so.name) si2.set("update_stock", 1) si2.get("items")[0].qty = 3 si2.insert() si2.submit() so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 9)
def test_update_child_qty_rate(self): so = make_sales_order(item_code="_Test Item", qty=4) create_dn_against_so(so.name, 4) make_sales_invoice(so.name) existing_reserved_qty = get_reserved_qty() trans_item = json.dumps([{ 'item_code': '_Test Item', 'rate': 200, 'qty': 7, 'docname': so.items[0].name }]) update_child_qty_rate('Sales Order', trans_item, so.name) so.reload() self.assertEqual(so.get("items")[0].rate, 200) self.assertEqual(so.get("items")[0].qty, 7) self.assertEqual(so.get("items")[0].amount, 1400) self.assertEqual(so.status, 'To Deliver and Bill') self.assertEqual(get_reserved_qty(), existing_reserved_qty + 3) trans_item = json.dumps([{ 'item_code': '_Test Item', 'rate': 200, 'qty': 2, 'docname': so.items[0].name }]) self.assertRaises(frappe.ValidationError, update_child_qty_rate, 'Sales Order', trans_item, so.name)
def test_update_child_adding_new_item(self): so = make_sales_order(item_code= "_Test Item", qty=4) create_dn_against_so(so.name, 4) make_sales_invoice(so.name) prev_total = so.get("base_total") prev_total_in_words = so.get("base_in_words") first_item_of_so = so.get("items")[0] trans_item = json.dumps([ {'item_code' : first_item_of_so.item_code, 'rate' : first_item_of_so.rate, \ 'qty' : first_item_of_so.qty, 'docname': first_item_of_so.name}, {'item_code' : '_Test Item 2', 'rate' : 200, 'qty' : 7} ]) update_child_qty_rate('Sales Order', trans_item, so.name) so.reload() self.assertEqual(so.get("items")[-1].item_code, '_Test Item 2') self.assertEqual(so.get("items")[-1].rate, 200) self.assertEqual(so.get("items")[-1].qty, 7) self.assertEqual(so.get("items")[-1].amount, 1400) self.assertEqual(so.status, 'To Deliver and Bill') updated_total = so.get("base_total") updated_total_in_words = so.get("base_in_words") self.assertEqual(updated_total, prev_total+1400) self.assertNotEqual(updated_total_in_words, prev_total_in_words)
def test_make_sales_invoice_with_terms(self): so = make_sales_order(do_not_submit=True) self.assertRaises(frappe.ValidationError, make_sales_invoice, so.name) so.update({"payment_terms_template": "_Test Payment Term Template"}) so.save() so.submit() si = make_sales_invoice(so.name) self.assertEquals(len(si.get("items")), len(so.get("items"))) self.assertEquals(len(si.get("items")), 1) si.insert() self.assertEqual(si.payment_schedule[0].payment_amount, 500.0) self.assertEqual(si.payment_schedule[0].due_date, so.transaction_date) self.assertEqual(si.payment_schedule[1].payment_amount, 500.0) self.assertEqual(si.payment_schedule[1].due_date, add_days(so.transaction_date, 30)) si.submit() si1 = make_sales_invoice(so.name) self.assertEquals(len(si1.get("items")), 0)
def test_update_qty(self): so = make_sales_order() create_dn_against_so(so.name, 6) so.load_from_db() self.assertEquals(so.get("items")[0].delivered_qty, 6) # Check delivered_qty after make_sales_invoice without update_stock checked si1 = make_sales_invoice(so.name) si1.get("items")[0].qty = 6 si1.insert() si1.submit() so.load_from_db() self.assertEquals(so.get("items")[0].delivered_qty, 6) # Check delivered_qty after make_sales_invoice with update_stock checked si2 = make_sales_invoice(so.name) si2.set("update_stock", 1) si2.get("items")[0].qty = 3 si2.insert() si2.submit() so.load_from_db() self.assertEquals(so.get("items")[0].delivered_qty, 9)
def test_make_sales_invoice_with_terms(self): so = make_sales_order(do_not_submit=True) self.assertRaises(frappe.ValidationError, make_sales_invoice, so.name) so.update({"payment_terms_template": "_Test Payment Term Template"}) so.save() so.submit() si = make_sales_invoice(so.name) self.assertEqual(len(si.get("items")), len(so.get("items"))) self.assertEqual(len(si.get("items")), 1) si.insert() si.set('taxes', []) si.save() self.assertEqual(si.payment_schedule[0].payment_amount, 500.0) self.assertEqual(si.payment_schedule[0].due_date, so.transaction_date) self.assertEqual(si.payment_schedule[1].payment_amount, 500.0) self.assertEqual(si.payment_schedule[1].due_date, add_days(so.transaction_date, 30)) si.submit() si1 = make_sales_invoice(so.name) self.assertEqual(len(si1.get("items")), 0)
def test_make_sales_invoice(self): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice so = frappe.bean(copy=test_records[0]).insert() self.assertRaises(frappe.ValidationError, make_sales_invoice, so.doc.name) sales_order = frappe.bean("Sales Order", so.doc.name) sales_order.submit() si = make_sales_invoice(so.doc.name) self.assertEquals(si[0]["doctype"], "Sales Invoice") self.assertEquals(len(si), len(sales_order.doclist)) self.assertEquals( len([d for d in si if d["doctype"] == "Sales Invoice Item"]), 1) si = frappe.bean(si) si.doc.posting_date = "2013-10-10" si.insert() si.submit() si1 = make_sales_invoice(so.doc.name) self.assertEquals( len([d for d in si1 if d["doctype"] == "Sales Invoice Item"]), 0)
def test_add_new_item_in_update_child_qty_rate(self): so = make_sales_order(item_code= "_Test Item", qty=4) create_dn_against_so(so.name, 4) make_sales_invoice(so.name) trans_item = json.dumps([{'item_code' : '_Test Item 2', 'rate' : 200, 'qty' : 7}]) update_child_qty_rate('Sales Order', trans_item, so.name) so.reload() self.assertEqual(so.get("items")[-1].item_code, '_Test Item 2') self.assertEqual(so.get("items")[-1].rate, 200) self.assertEqual(so.get("items")[-1].qty, 7) self.assertEqual(so.get("items")[-1].amount, 1400) self.assertEqual(so.status, 'To Deliver and Bill')
def test_remove_item_in_update_child_qty_rate(self): so = make_sales_order(**{ "item_list": [{ "item_code": '_Test Item', "qty": 5, "rate": 1000 }] }) create_dn_against_so(so.name, 2) make_sales_invoice(so.name) # add an item so as to try removing items trans_item = json.dumps([{ "item_code": '_Test Item', "qty": 5, "rate": 1000, "docname": so.get("items")[0].name }, { "item_code": '_Test Item 2', "qty": 2, "rate": 500 }]) update_child_qty_rate('Sales Order', trans_item, so.name) so.reload() self.assertEqual(len(so.get("items")), 2) # check if delivered items can be removed trans_item = json.dumps([{ "item_code": '_Test Item 2', "qty": 2, "rate": 500, "docname": so.get("items")[1].name }]) self.assertRaises(frappe.ValidationError, update_child_qty_rate, 'Sales Order', trans_item, so.name) #remove last added item trans_item = json.dumps([{ "item_code": '_Test Item', "qty": 5, "rate": 1000, "docname": so.get("items")[0].name }]) update_child_qty_rate('Sales Order', trans_item, so.name) so.reload() self.assertEqual(len(so.get("items")), 1) self.assertEqual(so.status, 'To Deliver and Bill')
def on_submit(self, method): #check if delivery note doesn't have a sales invoice if self.per_billed == 100: return for row in self.items: if row.against_sales_order and row.against_sales_invoice is None: sales_order = frappe.get_doc('Sales Order', row.against_sales_order) #check sales order is fully delivered and not billed if sales_order.per_billed != 0 or sales_order.per_delivered != 100: break #check sales order is fully paid if sales_order.grand_total != sales_order.advance_paid: break sales_invoice = frappe.new_doc('Sales Invoice') sales_invoice.update( {'ignore_pricing_rule': sales_order.ignore_pricing_rule}) sales_invoice = make_sales_invoice(row.against_sales_order, sales_invoice) sales_invoice.update({ "ais_automated_creation": 1, "disable_rounded_total": 1 }) #Get payment entry with Sales Order and add it to advance paid sales_invoice.set_advances() sales_invoice.submit()
def create_sales_invoice(shop_name: str, shopify_order: "Order", sales_order: "SalesOrder"): """ Helper function to create a Sales Invoice document for a Shopify order. Args: shop_name (str): The name of the Shopify configuration for the store. shopify_order (Order): The Shopify order data. sales_order (SalesOrder): The reference Sales Order document for the Shopify order. Returns: SalesInvoice: The created or existing Sales Invoice document, if any, otherwise None. """ shopify_settings: "ShopifySettings" = frappe.get_doc( "Shopify Settings", shop_name) if not cint(shopify_settings.sync_sales_invoice): return existing_invoice = get_shopify_document(shop_name=shop_name, doctype="Sales Invoice", order=shopify_order) if existing_invoice: existing_invoice: "SalesInvoice" frappe.db.set_value( "Sales Invoice", existing_invoice.name, { "shopify_settings": shopify_settings.name, "shopify_order_id": shopify_order.id, "shopify_order_number": shopify_order.attributes.get("order_number") }) return existing_invoice if sales_order.docstatus == 1 and not sales_order.per_billed: sales_invoice: "SalesInvoice" = make_sales_invoice( sales_order.name, ignore_permissions=True) sales_invoice.update({ "shopify_settings": shopify_settings.name, "shopify_order_id": shopify_order.id, "shopify_order_number": shopify_order.attributes.get("order_number"), "set_posting_time": True, "posting_date": getdate(shopify_order.attributes.get("created_at")), "naming_series": shopify_settings.sales_invoice_series or "SI-Shopify-" }) for item in sales_invoice.items: item.cost_center = shopify_settings.cost_center sales_invoice.flags.ignore_mandatory = True sales_invoice.insert(ignore_mandatory=True) frappe.db.commit() return sales_invoice
def test_create_quotation_with_margin(self): from erpnext.selling.doctype.quotation.quotation import make_sales_order from erpnext.selling.doctype.sales_order.sales_order \ import make_delivery_note, make_sales_invoice total_margin = flt((1500*18.75)/100 + 1500) test_records[0]['items'][0]['price_list_rate'] = 1500 test_records[0]['items'][0]['margin_type'] = 'Percentage' test_records[0]['items'][0]['margin_rate_or_amount'] = 18.75 quotation = frappe.copy_doc(test_records[0]) quotation.insert() self.assertEquals(quotation.get("items")[0].rate, total_margin) self.assertRaises(frappe.ValidationError, make_sales_order, quotation.name) quotation.submit() sales_order = make_sales_order(quotation.name) sales_order.delivery_date = "2016-01-02" sales_order.naming_series = "_T-Quotation-" sales_order.transaction_date = "2016-01-01" sales_order.insert() self.assertEquals(quotation.get("items")[0].rate, total_margin) sales_order.submit() dn = make_delivery_note(sales_order.name) self.assertEquals(quotation.get("items")[0].rate, total_margin) dn.save() si = make_sales_invoice(sales_order.name) self.assertEquals(quotation.get("items")[0].rate, total_margin) si.save()
def test_reserved_qty_for_over_delivery_via_sales_invoice(self): make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) # set over-delivery tolerance frappe.db.set_value('Item', "_Test Item", 'tolerance', 50) existing_reserved_qty = get_reserved_qty() so = make_sales_order() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) si = make_sales_invoice(so.name) si.update_stock = 1 si.get("items")[0].qty = 12 si.insert() si.submit() self.assertEqual(get_reserved_qty(), existing_reserved_qty) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 12) self.assertEqual(so.per_delivered, 100) si.cancel() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 0) self.assertEqual(so.per_delivered, 0)
def test_reserved_qty_for_over_delivery_via_sales_invoice(self): make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) # set over-delivery allowance frappe.db.set_value('Item', "_Test Item", 'over_delivery_receipt_allowance', 50) frappe.db.set_value('Item', "_Test Item", 'over_billing_allowance', 20) existing_reserved_qty = get_reserved_qty() so = make_sales_order() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) si = make_sales_invoice(so.name) si.update_stock = 1 si.get("items")[0].qty = 12 si.insert() si.submit() self.assertEqual(get_reserved_qty(), existing_reserved_qty) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 12) self.assertEqual(so.per_delivered, 100) si.cancel() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 0) self.assertEqual(so.per_delivered, 0)
def make_invoice(self): ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(self.reference_name, ignore_permissions=True) si = si.insert(ignore_permissions=True) si.submit()
def make_invoice(self): if self.make_sales_invoice: from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(self.reference_name, ignore_permissions=True) si = si.insert(ignore_permissions=True) si.submit()
def sync_magento_invoices(magento_order, magento_settings): erpnext_sales_order_name = frappe.db.get_value( "Sales Order", {"magento_order_id": magento_order.get("entity_id")}, "name") erpnext_sales_order = frappe.get_doc("Sales Order", erpnext_sales_order_name) for invoice in get_magento_order_invoices(magento_order.get("entity_id")): erpnext_sales_invoice_name = frappe.db.get_value( "Sales Invoice", {"magento_order_id": magento_order.get("entity_id")}, "name") if not erpnext_sales_invoice_name and erpnext_sales_order.docstatus == 1: erpnext_sales_invoice = make_sales_invoice( erpnext_sales_order.name) erpnext_sales_invoice.magento_order_id = magento_order.get( "entity_id") erpnext_sales_invoice.naming_series = magento_settings.sales_invoice_series or "erpnext_sales_invoice-Magento-" erpnext_sales_invoice.flags.ignore_mandatory = True set_cost_center(erpnext_sales_invoice.items, magento_settings.cost_center) erpnext_sales_invoice.save() frappe.db.commit() else: erpnext_sales_invoice = frappe.get_doc("Sales Invoice", erpnext_sales_invoice_name) if invoice.get("state") == 2: erpnext_sales_invoice.submit() frappe.db.commit() make_payament_entry_against_sales_invoice(erpnext_sales_invoice, magento_settings)
def test_create_quotation_with_margin(self): from erpnext.selling.doctype.quotation.quotation import make_sales_order from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice total_margin = flt((1500 * 18.75) / 100 + 1500) test_records[0]["items"][0]["price_list_rate"] = 1500 test_records[0]["items"][0]["margin_type"] = "Percentage" test_records[0]["items"][0]["margin_rate_or_amount"] = 18.75 quotation = frappe.copy_doc(test_records[0]) quotation.insert() self.assertEquals(quotation.get("items")[0].rate, total_margin) self.assertRaises(frappe.ValidationError, make_sales_order, quotation.name) quotation.submit() sales_order = make_sales_order(quotation.name) sales_order.delivery_date = "2016-01-02" sales_order.naming_series = "_T-Quotation-" sales_order.transaction_date = "2016-01-01" sales_order.insert() self.assertEquals(quotation.get("items")[0].rate, total_margin) sales_order.submit() dn = make_delivery_note(sales_order.name) self.assertEquals(quotation.get("items")[0].rate, total_margin) dn.save() si = make_sales_invoice(sales_order.name) self.assertEquals(quotation.get("items")[0].rate, total_margin) si.save()
def make_sales_invoice(serial_no): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice serialNoDoc = frappe.get_doc("Serial No", serial_no) if serialNoDoc: brn = serialNoDoc.booking_reference_number itemCode = serialNoDoc.item_code if itemCode: item_record = frappe.get_doc("Item", itemCode) record = frappe.db.sql("""select so.name from `tabSales Order` so where so.booking_reference_number = %s and so.docstatus = 1""", (brn)) if record: salesorder = frappe.get_doc("Sales Order", record[0][0]) if salesorder: salesinvoice = make_sales_invoice(salesorder.name) #salesinvoice.posting_date = frappe.utils.datetime.nowdate() salesinvoice.update_stock = True for itemrecords in salesinvoice.items: if itemrecords.item_code == itemCode: itemrecords.serial_no = serial_no itemrecords.warehouse = serialNoDoc.warehouse itemrecords.allow_zero_valuation_rate = True salesinvoice.insert() salesinvoice.save() #salesinvoice.submit() #submit in the submit_sales_invoice methd frappe.db.commit() return 'Success: sales invoice '+salesinvoice.name+' created for sales order '+salesorder.name+' with booking reference number '+brn else: return 'Error: Couldnt find the matching salesorder that is ready to be billed' else: return 'Error: The sales order for this vehicle doesnt exist' else: msg = """Error: The vehicle with the serial no {sln} does not exist on ERPNext""".format(sln = serial_no).encode('ascii') return msg
def test_make_sales_invoice(self): so = make_sales_order(do_not_submit=True) self.assertRaises(frappe.ValidationError, make_sales_invoice, so.name) so.submit() si = make_sales_invoice(so.name) self.assertEquals(len(si.get("items")), len(so.get("items"))) self.assertEquals(len(si.get("items")), 1) si.insert() si.submit() si1 = make_sales_invoice(so.name) self.assertEquals(len(si1.get("items")), 0)
def process_new_order(foxycart_data): foxycart_settings = frappe.get_single("Foxycart Settings") customer = find_customer(foxycart_data.get("customer_email")) # Hack to prevent permission issues if frappe.session.user == "Guest": frappe.set_user("Administrator") address = None if not customer: customer = make_customer(foxycart_data, foxycart_settings) address = make_address(customer, foxycart_data) else: address = find_address(customer, foxycart_data) if not address: address = make_address(customer, foxycart_data) sales_order = make_sales_order( customer, address, foxycart_data, foxycart_settings) sales_invoice = make_sales_invoice(sales_order, ignore_permissions=True) sales_invoice.save() sales_invoice.submit() frappe.db.commit() payment_entry = get_payment_entry("Sales Invoice", sales_invoice.name) payment_entry.reference_no = foxycart_data.get("id") payment_entry.reference_date = foxycart_data.get("transaction_date") payment_entry.flags.ignore_permissions= True payment_entry.save() payment_entry.submit() frappe.db.commit()
def make_invoice(self): ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(self.reference_name, ignore_permissions=True) si = si.insert(ignore_permissions=True) si.submit()
def make_sales_invoice_for_delivery(self): from erpnext.selling.doctype.sales_order import sales_order # If the delivery is already billed, don't create a Sales Invoice if self.per_billed == 100: return # Picking up sales orders for 2 reasons: # 1. A Delivery Note can be made against multiple orders, so they all need to be invoiced # 2. Using the `make_sales_invoice` in `delivery_note.py` doesn't consider already invoiced orders sales_orders = [item.against_sales_order for item in self.items if item.against_sales_order] sales_orders = list(set(sales_orders)) new_invoices = [] for order in sales_orders: invoice = sales_order.make_sales_invoice(order) if len(invoice.items) > 0: invoice.set_posting_time = True invoice.posting_date = self.posting_date invoice.posting_time = self.posting_time invoice.save() invoice.submit() new_invoices.append(get_link_to_form("Sales Invoice", invoice.name)) for item in self.items: item.against_sales_invoice = invoice.name if new_invoices: new_invoices = ", ".join(str(invoice) for invoice in new_invoices) frappe.msgprint(_("The following Sales Invoice(s) were automatically created: {0}".format(new_invoices)))
def make_invoice(self): if self.make_sales_invoice: from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(self.reference_name, ignore_permissions=True) si = si.insert(ignore_permissions=True) si.submit()
def create_sales_invoice(shopify_order, shopify_settings, so, old_order_sync=False): if not frappe.db.get_value("Sales Invoice", {"shopify_order_id": shopify_order.get("id")}, "name")\ and so.docstatus==1 and not so.per_billed and cint(shopify_settings.sync_sales_invoice): if old_order_sync: posting_date = getdate(shopify_order.get('created_at')) else: posting_date = nowdate() si = make_sales_invoice(so.name, ignore_permissions=True) si.shopify_order_id = shopify_order.get("id") si.shopify_order_number = shopify_order.get("name") si.set_posting_time = 1 si.posting_date = posting_date si.due_date = posting_date si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-" si.flags.ignore_mandatory = True set_cost_center(si.items, shopify_settings.cost_center) si.insert(ignore_mandatory=True) si.submit() make_payament_entry_against_sales_invoice(si, shopify_settings, posting_date) frappe.db.commit()
def test_reserved_qty_for_over_delivery_via_sales_invoice(self): # set over-delivery tolerance frappe.db.set_value('Item', "_Test Item", 'tolerance', 50) existing_reserved_qty = get_reserved_qty() so = make_sales_order() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) si = make_sales_invoice(so.name) si.update_stock = 1 si.get("items")[0].qty = 12 si.insert() si.submit() self.assertEqual(get_reserved_qty(), existing_reserved_qty) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 12) self.assertEqual(so.per_delivered, 100) si.cancel() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 0) self.assertEqual(so.per_delivered, 0)
def invoice_qol(name, payments, loyalty_card_no, loyalty_program, loyalty_points, cashback_receipt): def set_cost_center(item): if cost_center: item.cost_center = cost_center doc = make_sales_invoice(name) cost_center = (frappe.db.get_value( "Branch", doc.os_branch, "os_cost_center") if doc.os_branch else None) mapf(set_cost_center, doc.items) if loyalty_program and cint(loyalty_points): doc.redeem_loyalty_points = 1 doc.os_loyalty_card_no = loyalty_card_no doc.loyalty_program = loyalty_program doc.loyalty_points = cint(loyalty_points) doc.loyalty_redemption_cost_center = cost_center if cashback_receipt: doc.os_cashback_receipt = cashback_receipt get_payments = compose( partial(filterf, lambda x: x.get("amount") != 0), partial( map, partial(keyfilter, lambda x: x in ["mode_of_payment", "amount"])), json.loads, ) payments_proc = get_payments(payments) if payments_proc: doc.is_pos = 1 mapf(lambda x: doc.append("payments", x), payments_proc) doc.update_stock = 0 doc.insert(ignore_permissions=True) doc.submit() return doc.name
def test_sales_order_on_hold(self): so = make_sales_order(item_code="_Test Product Bundle Item") so.db_set('Status', "On Hold") si = make_sales_invoice(so.name) self.assertRaises(frappe.ValidationError, create_dn_against_so, so.name) self.assertRaises(frappe.ValidationError, si.submit)
def test_reserved_qty_for_over_delivery_via_sales_invoice(self): # set over-delivery tolerance frappe.db.set_value('Item', "_Test Item", 'tolerance', 50) existing_reserved_qty = get_reserved_qty() so = make_sales_order() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) si = make_sales_invoice(so.name) si.update_stock = 1 si.get("items")[0].qty = 12 si.insert() si.submit() total_projected_qty = get_total_projected_qty('_Test Item') item_doc = frappe.get_doc('Item', '_Test Item') self.assertEqual(total_projected_qty, item_doc.total_projected_qty) self.assertEqual(get_reserved_qty(), existing_reserved_qty) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 12) self.assertEqual(so.per_delivered, 100) si.cancel() self.assertEqual(get_reserved_qty(), existing_reserved_qty + 10) total_projected_qty = get_total_projected_qty('_Test Item') item_doc = frappe.get_doc('Item', '_Test Item') self.assertEqual(total_projected_qty, item_doc.total_projected_qty) so.load_from_db() self.assertEqual(so.get("items")[0].delivered_qty, 0) self.assertEqual(so.per_delivered, 0)
def test_make_sales_invoice(self): so = make_sales_order(do_not_submit=True) self.assertRaises(frappe.ValidationError, make_sales_invoice, so.name) so.submit() si = make_sales_invoice(so.name) self.assertEqual(len(si.get("items")), len(so.get("items"))) self.assertEqual(len(si.get("items")), 1) si.insert() si.submit() si1 = make_sales_invoice(so.name) self.assertEqual(len(si1.get("items")), 0)
def create_sales_invoice(self, so): sinv = make_sales_invoice(so.name) sinv.posting_date = so.transaction_date sinv.taxes_and_charges = "" sinv.taxes = "" sinv.insert() sinv.submit() return sinv
def create_sales_invoice(order, shopify_settings, so): if not frappe.db.get_value("Sales Invoice", {"shopify_id": order.get("id")}, "name") and so.docstatus==1 \ and not so.per_billed: si = make_sales_invoice(so.name) si.shopify_id = order.get("id") si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-" si.is_pos = 1 si.cash_bank_account = shopify_settings.cash_bank_account si.submit()
def create_sales_invoice(order, shopify_settings, so): if not frappe.db.get_value("Sales Invoice", {"shopify_id": order.get("id")}, "name") and so.docstatus==1 \ and not so.per_billed: si = make_sales_invoice(so.name) si.shopify_id = order.get("id") si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-" si.is_pos = 1 si.cash_bank_account = shopify_settings.cash_bank_account si.submit()
def work(): frappe.set_user(frappe.db.get_global('demo_accounts_user')) if random.random() <= 0.6: report = "Ordered Items to be Billed" for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0] != "Total"]))[:random.randint(1, 5)]: try: si = frappe.get_doc(make_sales_invoice(so)) si.posting_date = frappe.flags.current_date for d in si.get("items"): if not d.income_account: d.income_account = "Sales - {}".format( frappe.get_cached_value('Company', si.company, 'abbr')) si.insert() si.submit() frappe.db.commit() except frappe.ValidationError: pass if random.random() <= 0.6: report = "Received Items to be Billed" for pr in list(set([r[0] for r in query_report.run(report)["result"] if r[0] != "Total"]))[:random.randint(1, 5)]: try: pi = frappe.get_doc(make_purchase_invoice(pr)) pi.posting_date = frappe.flags.current_date pi.bill_no = random_string(6) pi.insert() pi.submit() frappe.db.commit() except frappe.ValidationError: pass if random.random() < 0.5: make_payment_entries("Sales Invoice", "Accounts Receivable") if random.random() < 0.5: make_payment_entries("Purchase Invoice", "Accounts Payable") if random.random() < 0.4: # make payment request against sales invoice sales_invoice_name = get_random( "Sales Invoice", filters={"docstatus": 1}) if sales_invoice_name: si = frappe.get_doc("Sales Invoice", sales_invoice_name) if si.outstanding_amount > 0: payment_request = make_payment_request(dt="Sales Invoice", dn=si.name, recipient_id=si.contact_email, submit_doc=True, mute_email=True, use_dummy_message=True) payment_entry = frappe.get_doc( make_payment_entry(payment_request.name)) payment_entry.posting_date = frappe.flags.current_date payment_entry.submit() make_pos_invoice()
def create_si_for_so(wbtname, so): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(so.name) si.weighbridge_ticket = wbtname si.save() frappe.db.commit() frappe.msgprint(_("Sales Invoice %s created successfully." % (si.name))) return si
def create_si_for_so(wbtname, so): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(so.name) si.weighbridge_ticket = wbtname si.save() frappe.db.commit() frappe.msgprint(_("Sales Invoice %s created successfully." % (si.name))) return si
def test_terms_copied(self): so = make_sales_order(do_not_copy=1, do_not_save=1) so.payment_terms_template = '_Test Payment Term Template' so.insert() so.submit() self.assertTrue(so.get('payment_schedule')) si = make_sales_invoice(so.name) si.insert() self.assertTrue(si.get('payment_schedule'))
def test_terms_copied(self): so = make_sales_order(do_not_copy=1, do_not_save=1) so.payment_terms_template = '_Test Payment Term Template' so.insert() so.submit() self.assertTrue(so.get('payment_schedule')) si = make_sales_invoice(so.name) si.insert() self.assertTrue(si.get('payment_schedule'))
def make_invoice(self): """generate an invoice from the payment request""" ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(self.reference_name, ignore_permissions=True) si.allocate_advances_automatically = True si = si.insert(ignore_permissions=True) si.submit()
def invoice_qol(name, payments): doc = make_sales_invoice(name) if payments: doc.is_pos = 1 payments_list = json.loads(payments) map(lambda x: doc.append('payments', x), payments_list) doc.insert(ignore_permissions=True) doc.submit() return doc.name
def create_sales_invoice(shopify_order, shopify_settings, so): if not frappe.db.get_value("Sales Invoice", {"shopify_order_id": shopify_order.get("id")}, "name")\ and so.docstatus==1 and not so.per_billed: si = make_sales_invoice(so.name) si.shopify_order_id = shopify_order.get("id") si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-" si.flags.ignore_mandatory = True set_cost_center(si.items, shopify_settings.cost_center) si.submit() make_payament_entry_against_sales_invoice(si, shopify_settings) frappe.db.commit()
def work(): frappe.set_user(frappe.db.get_global('demo_accounts_user')) if random.random() <= 0.6: report = "Ordered Items to be Billed" for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:random.randint(1, 5)]: try: si = frappe.get_doc(make_sales_invoice(so)) si.posting_date = frappe.flags.current_date for d in si.get("items"): if not d.income_account: d.income_account = "Sales - {}".format(frappe.db.get_value('Company', si.company, 'abbr')) si.insert() si.submit() frappe.db.commit() except frappe.ValidationError: pass if random.random() <= 0.6: report = "Received Items to be Billed" for pr in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:random.randint(1, 5)]: try: pi = frappe.get_doc(make_purchase_invoice(pr)) pi.posting_date = frappe.flags.current_date pi.bill_no = random_string(6) pi.insert() pi.submit() frappe.db.commit() except frappe.ValidationError: pass if random.random() < 0.5: make_payment_entries("Sales Invoice", "Accounts Receivable") if random.random() < 0.5: make_payment_entries("Purchase Invoice", "Accounts Payable") if random.random() < 0.1: #make payment request against sales invoice sales_invoice_name = get_random("Sales Invoice", filters={"docstatus": 1}) if sales_invoice_name: si = frappe.get_doc("Sales Invoice", sales_invoice_name) if si.outstanding_amount > 0: payment_request = make_payment_request(dt="Sales Invoice", dn=si.name, recipient_id=si.contact_email, submit_doc=True, mute_email=True, use_dummy_message=True) payment_entry = frappe.get_doc(make_payment_entry(payment_request.name)) payment_entry.posting_date = frappe.flags.current_date payment_entry.submit() make_pos_invoice()
def create_sales_invoice(woocommerce_order, woocommerce_settings, so): if not frappe.db.get_value("Sales Invoice", {"woocommerce_order_id": woocommerce_order.get("id")}, "name")\ and so.docstatus==1 and not so.per_billed: si = make_sales_invoice(so.name) si.woocommerce_order_id = woocommerce_order.get("id") si.naming_series = woocommerce_settings.sales_invoice_series or "SI-woocommerce-" si.flags.ignore_mandatory = True set_cost_center(si.items, woocommerce_settings.cost_center) si.submit() make_payament_entry_against_sales_invoice(si, woocommerce_settings) frappe.db.commit()
def test_update_child_qty_rate(self): so = make_sales_order(item_code= "_Test Item", qty=4) create_dn_against_so(so.name, 4) make_sales_invoice(so.name) existing_reserved_qty = get_reserved_qty() trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 7, 'docname': so.items[0].name}]) update_child_qty_rate('Sales Order', trans_item, so.name) so.reload() self.assertEqual(so.get("items")[0].rate, 200) self.assertEqual(so.get("items")[0].qty, 7) self.assertEqual(so.get("items")[0].amount, 1400) self.assertEqual(so.status, 'To Deliver and Bill') self.assertEqual(get_reserved_qty(), existing_reserved_qty + 3) trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 2, 'docname': so.items[0].name}]) self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Sales Order', trans_item, so.name)
def create_sales_invoice(order, shopify_settings, so): sales_invoice = frappe.db.get_value("Sales Order", {"shopify_id": order.get("id")},\ ["ifnull(per_billed, '') as per_billed"], as_dict=1) if not frappe.db.get_value("Sales Invoice", {"shopify_id": order.get("id")}, "name") and so.docstatus==1 \ and not sales_invoice["per_billed"]: si = make_sales_invoice(so.name) si.shopify_id = order.get("id") si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-" si.is_pos = 1 si.cash_bank_account = shopify_settings.cash_bank_account si.submit()
def run_accounts(current_date): if can_make("Sales Invoice"): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice report = "Ordered Items to be Billed" for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Sales Invoice")]: si = frappe.get_doc(make_sales_invoice(so)) si.posting_date = current_date si.fiscal_year = cstr(current_date.year) for d in si.get("entries"): if not d.income_account: d.income_account = "Sales - {}".format(company_abbr) si.insert() si.submit() frappe.db.commit() if can_make("Purchase Invoice"): from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice report = "Received Items to be Billed" for pr in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Purchase Invoice")]: pi = frappe.get_doc(make_purchase_invoice(pr)) pi.posting_date = current_date pi.fiscal_year = cstr(current_date.year) pi.bill_no = random_string(6) pi.insert() pi.submit() frappe.db.commit() if can_make("Payment Received"): from erpnext.accounts.doctype.journal_voucher.journal_voucher import get_payment_entry_from_sales_invoice report = "Accounts Receivable" for si in list(set([r[4] for r in query_report.run(report, {"report_date": current_date })["result"] if r[3]=="Sales Invoice"]))[:how_many("Payment Received")]: jv = frappe.get_doc(get_payment_entry_from_sales_invoice(si)) jv.posting_date = current_date jv.cheque_no = random_string(6) jv.cheque_date = current_date jv.fiscal_year = cstr(current_date.year) jv.insert() jv.submit() frappe.db.commit() if can_make("Payment Made"): from erpnext.accounts.doctype.journal_voucher.journal_voucher import get_payment_entry_from_purchase_invoice report = "Accounts Payable" for pi in list(set([r[4] for r in query_report.run(report, {"report_date": current_date })["result"] if r[3]=="Purchase Invoice"]))[:how_many("Payment Made")]: jv = frappe.get_doc(get_payment_entry_from_purchase_invoice(pi)) jv.posting_date = current_date jv.cheque_no = random_string(6) jv.cheque_date = current_date jv.fiscal_year = cstr(current_date.year) jv.insert() jv.submit() frappe.db.commit()
def test_make_sales_invoice(self): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice so = frappe.copy_doc(test_records[0]).insert() self.assertRaises(frappe.ValidationError, make_sales_invoice, so.name) sales_order = frappe.get_doc("Sales Order", so.name) sales_order.submit() si = make_sales_invoice(so.name) self.assertEquals(si.doctype, "Sales Invoice") self.assertEquals(len(si.get("entries")), len(sales_order.get("sales_order_details"))) self.assertEquals(len(si.get("entries")), 1) si.posting_date = "2013-10-10" si.insert() si.submit() si1 = make_sales_invoice(so.name) self.assertEquals(len(si1.get("entries")), 0)
def test_so_billed_amount_against_return_entry(self): from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_sales_return so = make_sales_order(do_not_submit=True) so.submit() si = make_sales_invoice(so.name) si.insert() si.submit() si1 = make_sales_return(si.name) si1.update_billed_amount_in_sales_order = 1 si1.submit() so.load_from_db() self.assertEquals(so.per_billed, 0)
def make_pos_invoice(): make_sales_order() for data in frappe.get_all('Sales Order', fields=["name"], filters = [["per_billed", "<", "100"]]): si = frappe.get_doc(make_sales_invoice(data.name)) si.is_pos =1 si.posting_date = frappe.flags.current_date for d in si.get("items"): if not d.income_account: d.income_account = "Sales - {}".format(frappe.db.get_value('Company', si.company, 'abbr')) si.set_missing_values() make_payment_entries_for_pos_invoice(si) si.insert() si.submit()
def run_accounts(current_date): if can_make("Sales Invoice"): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice report = "Ordered Items to be Billed" for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Sales Invoice")]: si = webnotes.bean(make_sales_invoice(so)) si.doc.posting_date = current_date si.insert() si.submit() webnotes.conn.commit() if can_make("Purchase Invoice"): from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice report = "Received Items to be Billed" for pr in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Purchase Invoice")]: pi = webnotes.bean(make_purchase_invoice(pr)) pi.doc.posting_date = current_date pi.doc.bill_no = random_string(6) pi.insert() pi.submit() webnotes.conn.commit() if can_make("Payment Received"): from erpnext.accounts.doctype.journal_voucher.journal_voucher import get_payment_entry_from_sales_invoice report = "Accounts Receivable" for si in list(set([r[4] for r in query_report.run(report, {"report_date": current_date })["result"] if r[3]=="Sales Invoice"]))[:how_many("Payment Received")]: jv = webnotes.bean(get_payment_entry_from_sales_invoice(si)) jv.doc.posting_date = current_date jv.doc.cheque_no = random_string(6) jv.doc.cheque_date = current_date jv.insert() jv.submit() webnotes.conn.commit() if can_make("Payment Made"): from erpnext.accounts.doctype.journal_voucher.journal_voucher import get_payment_entry_from_purchase_invoice report = "Accounts Payable" for pi in list(set([r[4] for r in query_report.run(report, {"report_date": current_date })["result"] if r[3]=="Purchase Invoice"]))[:how_many("Payment Made")]: jv = webnotes.bean(get_payment_entry_from_purchase_invoice(pi)) jv.doc.posting_date = current_date jv.doc.cheque_no = random_string(6) jv.doc.cheque_date = current_date jv.insert() jv.submit() webnotes.conn.commit()
def test_customer_credit_limit(self): from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice outstanding_amt = self.get_customer_outstanding_amount() credit_limit = get_credit_limit('_Test Customer', '_Test Company') if outstanding_amt <= 0.0: item_qty = int((abs(outstanding_amt) + 200)/100) make_sales_order(qty=item_qty) if credit_limit == 0.0: frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', outstanding_amt - 50.0) # Sales Order so = make_sales_order(do_not_submit=True) self.assertRaises(frappe.ValidationError, so.submit) # Delivery Note dn = create_delivery_note(do_not_submit=True) self.assertRaises(frappe.ValidationError, dn.submit) # Sales Invoice si = create_sales_invoice(do_not_submit=True) self.assertRaises(frappe.ValidationError, si.submit) if credit_limit > outstanding_amt: frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', credit_limit) # Makes Sales invoice from Sales Order so.save(ignore_permissions=True) si = make_sales_invoice(so.name) si.save(ignore_permissions=True) self.assertRaises(frappe.ValidationError, make_sales_order)
def test_serial_no_based_delivery(self): frappe.set_value("Stock Settings", None, "automatically_set_serial_nos_based_on_fifo", 1) from erpnext.stock.doctype.item.test_item import make_item item = make_item("_Reserved_Serialized_Item", {"is_stock_item": 1, "maintain_stock": 1, "has_serial_no": 1, "serial_no_series": "SI.####", "valuation_rate": 500, "item_defaults": [ { "default_warehouse": "_Test Warehouse - _TC", "company": "_Test Company" }] }) frappe.db.sql("""delete from `tabSerial No` where item_code=%s""", (item.item_code)) make_item("_Test Item A", {"maintain_stock": 1, "valuation_rate": 100, "item_defaults": [ { "default_warehouse": "_Test Warehouse - _TC", "company": "_Test Company" }] }) make_item("_Test Item B", {"maintain_stock": 1, "valuation_rate": 200, "item_defaults": [ { "default_warehouse": "_Test Warehouse - _TC", "company": "_Test Company" }] }) from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom make_bom(item=item.item_code, rate=1000, raw_materials = ['_Test Item A', '_Test Item B']) so = make_sales_order(**{ "item_list": [{ "item_code": item.item_code, "ensure_delivery_based_on_produced_serial_no": 1, "qty": 1, "rate":1000 }] }) so.submit() from erpnext.manufacturing.doctype.work_order.test_work_order import \ make_wo_order_test_record work_order = make_wo_order_test_record(item=item.item_code, qty=1, do_not_save=True) work_order.fg_warehouse = "_Test Warehouse - _TC" work_order.sales_order = so.name work_order.submit() make_stock_entry(item_code=item.item_code, target="_Test Warehouse - _TC", qty=1) item_serial_no = frappe.get_doc("Serial No", {"item_code": item.item_code}) from erpnext.manufacturing.doctype.work_order.work_order import \ make_stock_entry as make_production_stock_entry se = frappe.get_doc(make_production_stock_entry(work_order.name, "Manufacture", 1)) se.submit() reserved_serial_no = se.get("items")[2].serial_no serial_no_so = frappe.get_value("Serial No", reserved_serial_no, "sales_order") self.assertEqual(serial_no_so, so.name) dn = make_delivery_note(so.name) dn.save() self.assertEqual(reserved_serial_no, dn.get("items")[0].serial_no) item_line = dn.get("items")[0] item_line.serial_no = item_serial_no.name self.assertRaises(frappe.ValidationError, dn.submit) item_line = dn.get("items")[0] item_line.serial_no = reserved_serial_no self.assertTrue(dn.submit) dn.load_from_db() dn.cancel() si = make_sales_invoice(so.name) si.update_stock = 1 si.save() self.assertEqual(si.get("items")[0].serial_no, reserved_serial_no) item_line = si.get("items")[0] item_line.serial_no = item_serial_no.name self.assertRaises(frappe.ValidationError, dn.submit) item_line = si.get("items")[0] item_line.serial_no = reserved_serial_no self.assertTrue(si.submit) si.submit() si.load_from_db() si.cancel() si = make_sales_invoice(so.name) si.update_stock = 0 si.submit() from erpnext.accounts.doctype.sales_invoice.sales_invoice import \ make_delivery_note as make_delivery_note_from_invoice dn = make_delivery_note_from_invoice(si.name) dn.save() dn.submit() self.assertEqual(dn.get("items")[0].serial_no, reserved_serial_no) dn.load_from_db() dn.cancel() si.load_from_db() si.cancel() se.load_from_db() se.cancel() self.assertFalse(frappe.db.exists("Serial No", {"sales_order": so.name}))
def test_terms_not_copied(self): so = make_sales_order() self.assertTrue(so.get('payment_schedule')) si = make_sales_invoice(so.name) self.assertFalse(si.get('payment_schedule'))