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()
Esempio n. 2
0
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()
Esempio n. 3
0
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)
Esempio n. 5
0
    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)
Esempio n. 7
0
    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)
Esempio n. 8
0
	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)
Esempio n. 9
0
	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)
Esempio n. 10
0
    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)
Esempio n. 11
0
    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)
Esempio n. 12
0
	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)
Esempio n. 13
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)
Esempio n. 14
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()
Esempio n. 16
0
	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()
Esempio n. 17
0
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()
Esempio n. 18
0
	def on_cancel(self):
		if self.get('is_return'):
			return

		update_last_purchase_rate(self, is_submit = 0)
Esempio n. 19
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()
Esempio n. 20
0
    def on_cancel(self):
        if self.get('is_return'):
            return

        update_last_purchase_rate(self, is_submit=0)