def on_cancel(self): self.check_for_closed_status() # Check if Purchase Invoice has been submitted against current Purchase Order submitted = frappe.db.sql( """select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = %s and t1.docstatus = 1""", self.name) if submitted: frappe.throw( _("Purchase Invoice {0} is already submitted").format( submitted[0][0])) frappe.db.set(self, 'status', 'Cancelled') self.update_prevdoc_status() self.update_billing_status() if not self.is_return: update_last_purchase_rate(self, 0) # Updating stock ledger should always be called after updating prevdoc status, # because updating ordered qty in bin depends upon updated ordered qty in PO self.update_stock_ledger() self.make_gl_entries_on_cancel()
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name): data = json.loads(trans_items) for d in data: child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname")) if parent_doctype == "Sales Order" and flt(d.get("qty")) < child_item.delivered_qty: frappe.throw(_("Cannot set quantity less than delivered quantity")) if parent_doctype == "Purchase Order" and flt(d.get("qty")) < child_item.received_qty: frappe.throw(_("Cannot set quantity less than received quantity")) child_item.qty = flt(d.get("qty")) if child_item.billed_amt > (flt(d.get("rate")) * flt(d.get("qty"))): frappe.throw(_("Row #{0}: Cannot set Rate if amount is greater than billed amount for Item {1}.") .format(child_item.idx, child_item.item_code)) else: child_item.rate = flt(d.get("rate")) child_item.flags.ignore_validate_update_after_submit = True child_item.save() p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name) p_doctype.flags.ignore_validate_update_after_submit = True p_doctype.set_qty_as_per_stock_uom() p_doctype.calculate_taxes_and_totals() frappe.get_doc('Authorization Control').validate_approving_authority(p_doctype.doctype, p_doctype.company, p_doctype.base_grand_total) p_doctype.set_payment_schedule() if parent_doctype == 'Purchase Order': p_doctype.validate_minimum_order_qty() p_doctype.validate_budget() if p_doctype.is_against_so(): p_doctype.update_status_updater() else: p_doctype.check_credit_limit() p_doctype.save() if parent_doctype == 'Purchase Order': update_last_purchase_rate(p_doctype, is_submit = 1) p_doctype.update_prevdoc_status() p_doctype.update_requested_qty() p_doctype.update_ordered_qty() p_doctype.update_ordered_and_reserved_qty() p_doctype.update_receiving_percentage() if p_doctype.is_subcontracted == "Yes": p_doctype.update_reserved_qty_for_subcontract() else: p_doctype.update_reserved_qty() p_doctype.update_project() p_doctype.update_prevdoc_status('submit') p_doctype.update_delivery_status() p_doctype.update_blanket_order() p_doctype.update_billing_percentage() p_doctype.set_status()
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name): data = json.loads(trans_items) for d in data: child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname")) if parent_doctype == "Sales Order" and flt(d.get("qty")) < child_item.delivered_qty: frappe.throw(_("Cannot set quantity less than delivered quantity")) if parent_doctype == "Purchase Order" and flt(d.get("qty")) < child_item.received_qty: frappe.throw(_("Cannot set quantity less than received quantity")) child_item.qty = flt(d.get("qty")) if child_item.billed_amt > (flt(d.get("rate")) * flt(d.get("qty"))): frappe.throw(_("Row #{0}: Cannot set Rate if amount is greater than billed amount for Item {1}.") .format(child_item.idx, child_item.item_code)) else: child_item.rate = flt(d.get("rate")) child_item.flags.ignore_validate_update_after_submit = True child_item.save() p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name) p_doctype.flags.ignore_validate_update_after_submit = True p_doctype.set_qty_as_per_stock_uom() p_doctype.calculate_taxes_and_totals() frappe.get_doc('Authorization Control').validate_approving_authority(p_doctype.doctype, p_doctype.company, p_doctype.base_grand_total) p_doctype.set_payment_schedule() if parent_doctype == 'Purchase Order': p_doctype.validate_minimum_order_qty() p_doctype.validate_budget() if p_doctype.is_against_so(): p_doctype.update_status_updater() else: p_doctype.check_credit_limit() p_doctype.save() if parent_doctype == 'Purchase Order': update_last_purchase_rate(p_doctype, is_submit = 1) p_doctype.update_prevdoc_status() p_doctype.update_requested_qty() p_doctype.update_ordered_qty() p_doctype.update_ordered_and_reserved_qty() p_doctype.update_receiving_percentage() if p_doctype.is_subcontracted == "Yes": p_doctype.update_reserved_qty_for_subcontract() else: p_doctype.update_reserved_qty() p_doctype.update_project() p_doctype.update_prevdoc_status('submit') p_doctype.update_delivery_status() p_doctype.update_blanket_order() p_doctype.update_billing_percentage() p_doctype.set_status()
def on_cancel(self): if self.get('is_return'): return update_last_purchase_rate(self, is_submit = 0) if self.doctype in ['Purchase Receipt', 'Purchase Invoice']: field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt' self.delete_linked_asset() self.update_fixed_asset(field, delete_asset=True)
def on_cancel(self): if self.get('is_return'): return update_last_purchase_rate(self, is_submit=0) if self.doctype in ['Purchase Receipt', 'Purchase Invoice']: field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt' self.delete_linked_asset() self.update_fixed_asset(field, delete_asset=True)
def on_submit(self): if self.get('is_return'): return if self.doctype in ['Purchase Receipt', 'Purchase Invoice']: field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt' self.process_fixed_asset() self.update_fixed_asset(field) update_last_purchase_rate(self, is_submit = 1)
def on_submit(self): if self.get('is_return'): return if self.doctype in ['Purchase Receipt', 'Purchase Invoice']: field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt' self.process_fixed_asset() self.update_fixed_asset(field) update_last_purchase_rate(self, is_submit=1)
def on_submit(self): if self.get("is_return"): return if self.doctype in ["Purchase Receipt", "Purchase Invoice"]: field = "purchase_invoice" if self.doctype == "Purchase Invoice" else "purchase_receipt" self.process_fixed_asset() self.update_fixed_asset(field) if self.doctype in ["Purchase Order", "Purchase Receipt"]: update_last_purchase_rate(self, is_submit=1)
def on_submit(self): if self.is_against_so(): self.update_status_updater() self.update_prevdoc_status() self.update_requested_qty() self.update_ordered_qty() frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.company, self.base_grand_total) update_last_purchase_rate(self, is_submit = 1)
def on_submit(self): if self.is_against_so(): self.update_status_updater() self.update_prevdoc_status() self.update_requested_qty() self.update_ordered_qty() frappe.get_doc('Authorization Control').validate_approving_authority( self.doctype, self.company, self.base_grand_total) update_last_purchase_rate(self, is_submit=1)
def on_cancel(self): super(BuyingController, self).on_cancel() if self.get('is_return'): return if self.doctype in ['Purchase Order', 'Purchase Receipt']: update_last_purchase_rate(self, is_submit=0) if self.doctype in ['Purchase Receipt', 'Purchase Invoice']: field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt' self.delete_linked_asset() self.update_fixed_asset(field, delete_asset=True)
def on_cancel(self): super(BuyingController, self).on_cancel() if self.get("is_return"): return if self.doctype in ["Purchase Order", "Purchase Receipt"]: update_last_purchase_rate(self, is_submit=0) if self.doctype in ["Purchase Receipt", "Purchase Invoice"]: field = "purchase_invoice" if self.doctype == "Purchase Invoice" else "purchase_receipt" self.delete_linked_asset() self.update_fixed_asset(field, delete_asset=True)
def on_cancel(self): if self.is_against_so(): self.update_status_updater() if self.has_drop_ship_item(): self.update_delivered_qty_in_sales_order() self.check_for_closed_status() frappe.db.set(self, 'status', 'Cancelled') self.update_prevdoc_status() # Must be called after updating ordered qty in Material Request self.update_requested_qty() self.update_ordered_qty() update_last_purchase_rate(self, is_submit=0)
def on_cancel(self): if self.is_against_so(): self.update_status_updater() if self.has_drop_ship_item(): self.update_delivered_qty_in_sales_order() self.check_for_closed_status() frappe.db.set(self,'status','Cancelled') self.update_prevdoc_status() # Must be called after updating ordered qty in Material Request self.update_requested_qty() self.update_ordered_qty() update_last_purchase_rate(self, is_submit = 0)
def on_submit(self): # Check for Approving Authority frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.company, self.base_grand_total) self.update_prevdoc_status() if self.per_billed < 100: self.update_billing_status() if not self.is_return: update_last_purchase_rate(self, 1) # Updating stock ledger should always be called after updating prevdoc status, # because updating ordered qty in bin depends upon updated ordered qty in PO self.update_stock_ledger() from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit update_serial_nos_after_submit(self, "items") self.make_gl_entries()
def on_cancel(self): self.check_for_closed_status() # Check if Purchase Invoice has been submitted against current Purchase Order submitted = frappe.db.sql("""select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = %s and t1.docstatus = 1""", self.name) if submitted: frappe.throw(_("Purchase Invoice {0} is already submitted").format(submitted[0][0])) self.update_prevdoc_status() self.update_billing_status() if not self.is_return: update_last_purchase_rate(self, 0) # Updating stock ledger should always be called after updating prevdoc status, # because updating ordered qty in bin depends upon updated ordered qty in PO self.update_stock_ledger() self.make_gl_entries_on_cancel()
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"): data = json.loads(trans_items) sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation'] parent = frappe.get_doc(parent_doctype, parent_doctype_name) for d in data: new_child_flag = False if not d.get("docname"): new_child_flag = True if parent_doctype == "Sales Order": child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code")) if parent_doctype == "Purchase Order": child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code")) else: child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname")) if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty): frappe.throw(_("Cannot set quantity less than delivered quantity")) if parent_doctype == "Purchase Order" and flt(d.get("qty")) < flt(child_item.received_qty): frappe.throw(_("Cannot set quantity less than received quantity")) child_item.qty = flt(d.get("qty")) precision = child_item.precision("rate") or 2 if flt(child_item.billed_amt, precision) > flt(flt(d.get("rate")) * flt(d.get("qty")), precision): frappe.throw(_("Row #{0}: Cannot set Rate if amount is greater than billed amount for Item {1}.") .format(child_item.idx, child_item.item_code)) else: child_item.rate = flt(d.get("rate")) if flt(child_item.price_list_rate): if flt(child_item.rate) > flt(child_item.price_list_rate): # if rate is greater than price_list_rate, set margin # or set discount child_item.discount_percentage = 0 if parent_doctype in sales_doctypes: child_item.margin_type = "Amount" child_item.margin_rate_or_amount = flt(child_item.rate - child_item.price_list_rate, child_item.precision("margin_rate_or_amount")) child_item.rate_with_margin = child_item.rate else: child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, child_item.precision("discount_percentage")) child_item.discount_amount = flt( child_item.price_list_rate) - flt(child_item.rate) if parent_doctype in sales_doctypes: child_item.margin_type = "" child_item.margin_rate_or_amount = 0 child_item.rate_with_margin = 0 child_item.flags.ignore_validate_update_after_submit = True if new_child_flag: child_item.idx = len(parent.items) + 1 child_item.insert() else: child_item.save() parent.reload() parent.flags.ignore_validate_update_after_submit = True parent.set_qty_as_per_stock_uom() parent.calculate_taxes_and_totals() if parent_doctype == "Sales Order": parent.set_gross_profit() frappe.get_doc('Authorization Control').validate_approving_authority(parent.doctype, parent.company, parent.base_grand_total) parent.set_payment_schedule() if parent_doctype == 'Purchase Order': parent.validate_minimum_order_qty() parent.validate_budget() if parent.is_against_so(): parent.update_status_updater() else: parent.check_credit_limit() parent.save() if parent_doctype == 'Purchase Order': update_last_purchase_rate(parent, is_submit = 1) parent.update_prevdoc_status() parent.update_requested_qty() parent.update_ordered_qty() parent.update_ordered_and_reserved_qty() parent.update_receiving_percentage() if parent.is_subcontracted == "Yes": parent.update_reserved_qty_for_subcontract() else: parent.update_reserved_qty() parent.update_project() parent.update_prevdoc_status('submit') parent.update_delivery_status() parent.update_blanket_order() parent.update_billing_percentage() parent.set_status()
def on_cancel(self): if self.get('is_return'): return update_last_purchase_rate(self, is_submit = 0)
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"): def check_doc_permissions(doc, perm_type="create"): try: doc.check_permission(perm_type) except frappe.PermissionError: actions = {"create": "add", "write": "update"} frappe.throw( _("You do not have permissions to {} items in a {}.").format( actions[perm_type], parent_doctype), title=_("Insufficient Permissions"), ) def validate_workflow_conditions(doc): workflow = get_workflow_name(doc.doctype) if not workflow: return workflow_doc = frappe.get_doc("Workflow", workflow) current_state = doc.get(workflow_doc.workflow_state_field) roles = frappe.get_roles() transitions = [] for transition in workflow_doc.transitions: if transition.next_state == current_state and transition.allowed in roles: if not is_transition_condition_satisfied(transition, doc): continue transitions.append(transition.as_dict()) if not transitions: frappe.throw( _("You are not allowed to update as per the conditions set in {} Workflow." ).format(get_link_to_form("Workflow", workflow)), title=_("Insufficient Permissions"), ) def get_new_child_item(item_row): child_doctype = "Sales Order Item" if parent_doctype == "Sales Order" else "Purchase Order Item" return set_order_defaults(parent_doctype, parent_doctype_name, child_doctype, child_docname, item_row) def validate_quantity(child_item, d): if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt( child_item.delivered_qty): frappe.throw(_("Cannot set quantity less than delivered quantity")) if parent_doctype == "Purchase Order" and flt(d.get("qty")) < flt( child_item.received_qty): frappe.throw(_("Cannot set quantity less than received quantity")) data = json.loads(trans_items) sales_doctypes = [ "Sales Order", "Sales Invoice", "Delivery Note", "Quotation" ] parent = frappe.get_doc(parent_doctype, parent_doctype_name) check_doc_permissions(parent, "write") validate_and_delete_children(parent, data) for d in data: new_child_flag = False if not d.get("item_code"): # ignore empty rows continue if not d.get("docname"): new_child_flag = True check_doc_permissions(parent, "create") child_item = get_new_child_item(d) else: check_doc_permissions(parent, "write") child_item = frappe.get_doc(parent_doctype + " Item", d.get("docname")) prev_rate, new_rate = flt(child_item.get("rate")), flt( d.get("rate")) prev_qty, new_qty = flt(child_item.get("qty")), flt(d.get("qty")) prev_con_fac, new_con_fac = flt( child_item.get("conversion_factor")), flt( d.get("conversion_factor")) prev_uom, new_uom = child_item.get("uom"), d.get("uom") if parent_doctype == "Sales Order": prev_date, new_date = child_item.get("delivery_date"), d.get( "delivery_date") elif parent_doctype == "Purchase Order": prev_date, new_date = child_item.get("schedule_date"), d.get( "schedule_date") rate_unchanged = prev_rate == new_rate qty_unchanged = prev_qty == new_qty uom_unchanged = prev_uom == new_uom conversion_factor_unchanged = prev_con_fac == new_con_fac date_unchanged = (prev_date == getdate(new_date) if prev_date and new_date else False ) # in case of delivery note etc if (rate_unchanged and qty_unchanged and conversion_factor_unchanged and uom_unchanged and date_unchanged): continue validate_quantity(child_item, d) child_item.qty = flt(d.get("qty")) rate_precision = child_item.precision("rate") or 2 conv_fac_precision = child_item.precision("conversion_factor") or 2 qty_precision = child_item.precision("qty") or 2 if flt(child_item.billed_amt, rate_precision) > flt( flt(d.get("rate"), rate_precision) * flt(d.get("qty"), qty_precision), rate_precision): frappe.throw( _("Row #{0}: Cannot set Rate if amount is greater than billed amount for Item {1}." ).format(child_item.idx, child_item.item_code)) else: child_item.rate = flt(d.get("rate"), rate_precision) if d.get("conversion_factor"): if child_item.stock_uom == child_item.uom: child_item.conversion_factor = 1 else: child_item.conversion_factor = flt(d.get("conversion_factor"), conv_fac_precision) if d.get("uom"): child_item.uom = d.get("uom") conversion_factor = flt( get_conversion_factor(child_item.item_code, child_item.uom).get("conversion_factor")) child_item.conversion_factor = (flt(d.get("conversion_factor"), conv_fac_precision) or conversion_factor) if d.get("delivery_date") and parent_doctype == "Sales Order": child_item.delivery_date = d.get("delivery_date") if d.get("schedule_date") and parent_doctype == "Purchase Order": child_item.schedule_date = d.get("schedule_date") if flt(child_item.price_list_rate): if flt(child_item.rate) > flt(child_item.price_list_rate): # if rate is greater than price_list_rate, set margin # or set discount child_item.discount_percentage = 0 if parent_doctype in sales_doctypes: child_item.margin_type = "Amount" child_item.margin_rate_or_amount = flt( child_item.rate - child_item.price_list_rate, child_item.precision("margin_rate_or_amount")) child_item.rate_with_margin = child_item.rate else: child_item.discount_percentage = flt( (1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, child_item.precision("discount_percentage"), ) child_item.discount_amount = flt( child_item.price_list_rate) - flt(child_item.rate) if parent_doctype in sales_doctypes: child_item.margin_type = "" child_item.margin_rate_or_amount = 0 child_item.rate_with_margin = 0 child_item.flags.ignore_validate_update_after_submit = True if new_child_flag: parent.load_from_db() child_item.idx = len(parent.items) + 1 child_item.insert() else: child_item.save() parent.reload() parent.flags.ignore_validate_update_after_submit = True parent.set_qty_as_per_stock_uom() parent.calculate_taxes_and_totals() parent.set_total_in_words() if parent_doctype == "Sales Order": make_packing_list(parent) parent.set_gross_profit() frappe.get_doc("Authorization Control").validate_approving_authority( parent.doctype, parent.company, parent.base_grand_total) parent.set_payment_schedule() if parent_doctype == "Purchase Order": parent.validate_minimum_order_qty() parent.validate_budget() if parent.is_against_so(): parent.update_status_updater() else: parent.check_credit_limit() # reset index of child table for idx, row in enumerate(parent.get(child_docname), start=1): row.idx = idx parent.save() if parent_doctype == "Purchase Order": update_last_purchase_rate(parent, is_submit=1) parent.update_prevdoc_status() parent.update_requested_qty() parent.update_ordered_qty() parent.update_ordered_and_reserved_qty() parent.update_receiving_percentage() if parent.is_subcontracted == "Yes": parent.update_reserved_qty_for_subcontract() parent.create_raw_materials_supplied("supplied_items") parent.save() else: parent.update_reserved_qty() parent.update_project() parent.update_prevdoc_status("submit") parent.update_delivery_status() parent.reload() validate_workflow_conditions(parent) parent.update_blanket_order() parent.update_billing_percentage() parent.set_status()
def on_cancel(self): if self.get('is_return'): return update_last_purchase_rate(self, is_submit=0)