Merge pull request #43282 from blaggacao/feat/email-to-empty-pi
feat: allow to create empty pi via email append to
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
"creation": "2013-05-21 16:16:39",
|
"creation": "2013-05-21 16:16:39",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
|
"email_append_to": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"title",
|
"title",
|
||||||
@@ -192,6 +193,7 @@
|
|||||||
"is_internal_supplier",
|
"is_internal_supplier",
|
||||||
"represents_company",
|
"represents_company",
|
||||||
"supplier_group",
|
"supplier_group",
|
||||||
|
"sender",
|
||||||
"column_break_147",
|
"column_break_147",
|
||||||
"inter_company_invoice_reference",
|
"inter_company_invoice_reference",
|
||||||
"is_old_subcontracting_flow",
|
"is_old_subcontracting_flow",
|
||||||
@@ -1625,13 +1627,19 @@
|
|||||||
"fieldname": "update_outstanding_for_self",
|
"fieldname": "update_outstanding_for_self",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Update Outstanding for Self"
|
"label": "Update Outstanding for Self"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "sender",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Sender",
|
||||||
|
"options": "Email"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 204,
|
"idx": 204,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-07-25 19:42:36.931278",
|
"modified": "2024-09-18 12:24:44.826539",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice",
|
"name": "Purchase Invoice",
|
||||||
@@ -1687,6 +1695,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"search_fields": "posting_date, supplier, bill_no, base_grand_total, outstanding_amount",
|
"search_fields": "posting_date, supplier, bill_no, base_grand_total, outstanding_amount",
|
||||||
|
"sender_field": "sender",
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "creation",
|
"sort_field": "creation",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
rounding_adjustment: DF.Currency
|
rounding_adjustment: DF.Currency
|
||||||
scan_barcode: DF.Data | None
|
scan_barcode: DF.Data | None
|
||||||
select_print_heading: DF.Link | None
|
select_print_heading: DF.Link | None
|
||||||
|
sender: DF.Data | None
|
||||||
set_from_warehouse: DF.Link | None
|
set_from_warehouse: DF.Link | None
|
||||||
set_posting_time: DF.Check
|
set_posting_time: DF.Check
|
||||||
set_warehouse: DF.Link | None
|
set_warehouse: DF.Link | None
|
||||||
|
|||||||
@@ -2025,6 +2025,16 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
|
|||||||
]
|
]
|
||||||
check_gl_entries(self, pi.name, expected_gle, nowdate())
|
check_gl_entries(self, pi.name, expected_gle, nowdate())
|
||||||
|
|
||||||
|
def test_create_purchase_invoice_without_mandatory(self):
|
||||||
|
pi = frappe.new_doc("Purchase Invoice")
|
||||||
|
pi.flags.ignore_mandatory = True
|
||||||
|
pi.insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
self.assertTrue(pi.name)
|
||||||
|
self.assertEqual(pi.docstatus, 0)
|
||||||
|
|
||||||
|
pi.delete()
|
||||||
|
|
||||||
@change_settings("Buying Settings", {"supplier_group": None})
|
@change_settings("Buying Settings", {"supplier_group": None})
|
||||||
def test_purchase_invoice_without_supplier_group(self):
|
def test_purchase_invoice_without_supplier_group(self):
|
||||||
# Create a Supplier
|
# Create a Supplier
|
||||||
|
|||||||
@@ -148,14 +148,16 @@ class AccountsController(TransactionBase):
|
|||||||
def ensure_supplier_is_not_blocked(self):
|
def ensure_supplier_is_not_blocked(self):
|
||||||
is_supplier_payment = self.doctype == "Payment Entry" and self.party_type == "Supplier"
|
is_supplier_payment = self.doctype == "Payment Entry" and self.party_type == "Supplier"
|
||||||
is_buying_invoice = self.doctype in ["Purchase Invoice", "Purchase Order"]
|
is_buying_invoice = self.doctype in ["Purchase Invoice", "Purchase Order"]
|
||||||
|
supplier_name = self.supplier if is_buying_invoice else self.party if is_supplier_payment else None
|
||||||
supplier = None
|
supplier = None
|
||||||
supplier_name = None
|
|
||||||
|
|
||||||
if is_buying_invoice or is_supplier_payment:
|
if supplier_name:
|
||||||
supplier_name = self.supplier if is_buying_invoice else self.party
|
supplier = frappe.get_doc(
|
||||||
supplier = frappe.get_doc("Supplier", supplier_name)
|
"Supplier",
|
||||||
|
supplier_name,
|
||||||
|
)
|
||||||
|
|
||||||
if supplier and supplier_name and supplier.on_hold:
|
if supplier and supplier.on_hold:
|
||||||
if (is_buying_invoice and supplier.hold_type in ["All", "Invoices"]) or (
|
if (is_buying_invoice and supplier.hold_type in ["All", "Invoices"]) or (
|
||||||
is_supplier_payment and supplier.hold_type in ["All", "Payments"]
|
is_supplier_payment and supplier.hold_type in ["All", "Payments"]
|
||||||
):
|
):
|
||||||
@@ -2170,8 +2172,8 @@ class AccountsController(TransactionBase):
|
|||||||
date = self.get("due_date")
|
date = self.get("due_date")
|
||||||
due_date = date or posting_date
|
due_date = date or posting_date
|
||||||
|
|
||||||
base_grand_total = self.get("base_rounded_total") or self.base_grand_total
|
base_grand_total = flt(self.get("base_rounded_total") or self.base_grand_total)
|
||||||
grand_total = self.get("rounded_total") or self.grand_total
|
grand_total = flt(self.get("rounded_total") or self.grand_total)
|
||||||
automatically_fetch_payment_terms = 0
|
automatically_fetch_payment_terms = 0
|
||||||
|
|
||||||
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
@@ -2245,6 +2247,8 @@ class AccountsController(TransactionBase):
|
|||||||
self.ignore_default_payment_terms_template = 1
|
self.ignore_default_payment_terms_template = 1
|
||||||
|
|
||||||
def get_order_details(self):
|
def get_order_details(self):
|
||||||
|
if not self.get("items"):
|
||||||
|
return None, None, None
|
||||||
if self.doctype == "Sales Invoice":
|
if self.doctype == "Sales Invoice":
|
||||||
po_or_so = self.get("items")[0].get("sales_order")
|
po_or_so = self.get("items")[0].get("sales_order")
|
||||||
po_or_so_doctype = "Sales Order"
|
po_or_so_doctype = "Sales Order"
|
||||||
@@ -2355,8 +2359,8 @@ class AccountsController(TransactionBase):
|
|||||||
total += flt(d.payment_amount, d.precision("payment_amount"))
|
total += flt(d.payment_amount, d.precision("payment_amount"))
|
||||||
base_total += flt(d.base_payment_amount, d.precision("base_payment_amount"))
|
base_total += flt(d.base_payment_amount, d.precision("base_payment_amount"))
|
||||||
|
|
||||||
base_grand_total = self.get("base_rounded_total") or self.base_grand_total
|
base_grand_total = flt(self.get("base_rounded_total") or self.base_grand_total)
|
||||||
grand_total = self.get("rounded_total") or self.grand_total
|
grand_total = flt(self.get("rounded_total") or self.grand_total)
|
||||||
|
|
||||||
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
base_grand_total = base_grand_total - flt(self.base_write_off_amount)
|
base_grand_total = base_grand_total - flt(self.base_write_off_amount)
|
||||||
|
|||||||
@@ -251,16 +251,16 @@ class BuyingController(SubcontractingController):
|
|||||||
|
|
||||||
if self.meta.get_field("base_in_words"):
|
if self.meta.get_field("base_in_words"):
|
||||||
if self.meta.get_field("base_rounded_total") and not self.is_rounded_total_disabled():
|
if self.meta.get_field("base_rounded_total") and not self.is_rounded_total_disabled():
|
||||||
amount = abs(self.base_rounded_total)
|
amount = abs(flt(self.base_rounded_total))
|
||||||
else:
|
else:
|
||||||
amount = abs(self.base_grand_total)
|
amount = abs(flt(self.base_grand_total))
|
||||||
self.base_in_words = money_in_words(amount, self.company_currency)
|
self.base_in_words = money_in_words(amount, self.company_currency)
|
||||||
|
|
||||||
if self.meta.get_field("in_words"):
|
if self.meta.get_field("in_words"):
|
||||||
if self.meta.get_field("rounded_total") and not self.is_rounded_total_disabled():
|
if self.meta.get_field("rounded_total") and not self.is_rounded_total_disabled():
|
||||||
amount = abs(self.rounded_total)
|
amount = abs(flt(self.rounded_total))
|
||||||
else:
|
else:
|
||||||
amount = abs(self.grand_total)
|
amount = abs(flt(self.grand_total))
|
||||||
|
|
||||||
self.in_words = money_in_words(amount, self.currency)
|
self.in_words = money_in_words(amount, self.currency)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user