예제 #1
0
    def get_calendar_events(self, user_id):
        from frappe.core.doctype.event.event import get_events

        events = get_events(self.future_from_date.strftime("%Y-%m-%d"), self.future_to_date.strftime("%Y-%m-%d"))

        html = ""
        if events:
            for i, e in enumerate(events):
                if i >= 10:
                    break
                if e.all_day:
                    html += """<li style='line-height: 200%%'>%s [%s (%s)]</li>""" % (
                        e.subject,
                        datetime_in_user_format(e.starts_on),
                        _("All Day"),
                    )
                else:
                    html += "<li style='line-height: 200%%'>%s [%s - %s]</li>" % (
                        e.subject,
                        datetime_in_user_format(e.starts_on),
                        datetime_in_user_format(e.ends_on),
                    )

        if html:
            return 1, "<h4>Upcoming Calendar Events (max 10):</h4><ul>" + html + "</ul><hr>"
        else:
            return 0, "<p>Calendar Events</p>"
예제 #2
0
    def validate_return_reference_doc(self):
        """validate item with reference doc"""
        ref = get_return_doc_and_details(self)

        if ref.doc:
            # validate docstatus
            if ref.doc.docstatus != 1:
                frappe.throw(
                    _("{0} {1} must be submitted").format(
                        ref.doc.doctype, ref.doc.name),
                    frappe.InvalidStatusError)

            # update stock check
            if ref.doc.doctype == "Sales Invoice" and cint(
                    ref.doc.update_stock) != 1:
                frappe.throw(
                    _("'Update Stock' for Sales Invoice {0} must be set").
                    format(ref.doc.name), NotUpdateStockError)

            # posting date check
            ref_posting_datetime = "%s %s" % (cstr(
                ref.doc.posting_date), cstr(ref.doc.posting_time)
                                              or "00:00:00")
            this_posting_datetime = "%s %s" % (cstr(
                self.posting_date), cstr(self.posting_time))
            if this_posting_datetime < ref_posting_datetime:
                from frappe.utils.dateutils import datetime_in_user_format
                frappe.throw(
                    _("Posting timestamp must be after {0}").format(
                        datetime_in_user_format(ref_posting_datetime)))

            stock_items = get_stock_items_for_return(ref.doc, ref.parentfields)
            already_returned_item_qty = self.get_already_returned_item_qty(
                ref.fieldname)

            for item in self.get("mtn_details"):
                # validate if item exists in the ref doc and that it is a stock item
                if item.item_code not in stock_items:
                    frappe.throw(
                        _("Item {0} does not exist in {1} {2}").format(
                            item.item_code, ref.doc.doctype, ref.doc.name),
                        frappe.DoesNotExistError)

                # validate quantity <= ref item's qty - qty already returned
                ref_item = ref.doc.getone({"item_code": item.item_code})
                returnable_qty = ref_item.qty - flt(
                    already_returned_item_qty.get(item.item_code))
                if not returnable_qty:
                    frappe.throw(
                        _("Item {0} has already been returned").format(
                            item.item_code), StockOverReturnError)
                elif item.transfer_qty > returnable_qty:
                    frappe.throw(
                        _("Cannot return more than {0} for Item {1}").format(
                            returnable_qty, item.item_code),
                        StockOverReturnError)
예제 #3
0
	def get_calendar_events(self, user_id):
		from frappe.core.doctype.event.event import get_events
		events = get_events(self.future_from_date.strftime("%Y-%m-%d"), self.future_to_date.strftime("%Y-%m-%d"))

		html = ""
		if events:
			for i, e in enumerate(events):
				if i>=10:
					break
				if e.all_day:
					html += """<li style='line-height: 200%%'>%s [%s (%s)]</li>""" % \
						(e.subject, datetime_in_user_format(e.starts_on), _("All Day"))
				else:
					html += "<li style='line-height: 200%%'>%s [%s - %s]</li>" % \
						(e.subject, datetime_in_user_format(e.starts_on), datetime_in_user_format(e.ends_on))

		if html:
			return 1, "<h4>" + _("Upcoming Calendar Events (max 10)") + ":</h4><ul>" + html + "</ul><hr>"
		else:
			return 0, "<p>" + _("Calendar Events") + "</p>"
예제 #4
0
	def validate_return_reference_doc(self):
		"""validate item with reference doc"""
		ref = get_return_doclist_and_details(self.doc.fields)
		
		if ref.doclist:
			# validate docstatus
			if ref.doclist[0].docstatus != 1:
				frappe.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": ' 
					+ _("Status should be Submitted"), raise_exception=frappe.InvalidStatusError)
			
			# update stock check
			if ref.doclist[0].doctype == "Sales Invoice" and cint(ref.doclist[0].update_stock) != 1:
				frappe.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": ' 
					+ _("Update Stock should be checked."), 
					raise_exception=NotUpdateStockError)
			
			# posting date check
			ref_posting_datetime = "%s %s" % (cstr(ref.doclist[0].posting_date), 
				cstr(ref.doclist[0].posting_time) or "00:00:00")
			this_posting_datetime = "%s %s" % (cstr(self.doc.posting_date), 
				cstr(self.doc.posting_time))
			if this_posting_datetime < ref_posting_datetime:
				from frappe.utils.dateutils import datetime_in_user_format
				frappe.msgprint(_("Posting Date Time cannot be before")
					+ ": " + datetime_in_user_format(ref_posting_datetime),
					raise_exception=True)
			
			stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields)
			already_returned_item_qty = self.get_already_returned_item_qty(ref.fieldname)
			
			for item in self.doclist.get({"parentfield": "mtn_details"}):
				# validate if item exists in the ref doclist and that it is a stock item
				if item.item_code not in stock_items:
					msgprint(_("Item") + ': "' + item.item_code + _("\" does not exist in ") +
						ref.doclist[0].doctype + ": " + ref.doclist[0].name, 
						raise_exception=frappe.DoesNotExistError)
				
				# validate quantity <= ref item's qty - qty already returned
				ref_item = ref.doclist.getone({"item_code": item.item_code})
				returnable_qty = ref_item.qty - flt(already_returned_item_qty.get(item.item_code))
				if not returnable_qty:
					frappe.throw("{item}: {item_code} {returned}".format(
						item=_("Item"), item_code=item.item_code, 
						returned=_("already returned though some other documents")), 
						StockOverReturnError)
				elif item.transfer_qty > returnable_qty:
					frappe.throw("{item}: {item_code}, {returned}: {qty}".format(
						item=_("Item"), item_code=item.item_code,
						returned=_("Max Returnable Qty"), qty=returnable_qty), StockOverReturnError)
예제 #5
0
def track_packages():
    # track packages and update the status
    # get all the packing_slips name
    date_format = convert_user_date_format()
    now = dt.strptime(datetime_in_user_format(dt.now()), date_format)
    #scheduler_events should run on 8AM, 12PM, and 5PM
    condition = (
        (now > now.replace(hour=8, minute=0, second=0, microsecond=0)
         and now < now.replace(hour=9, minute=0, second=0, microsecond=0))
        or (now > now.replace(hour=12, minute=0, second=0, microsecond=0)
            and now < now.replace(hour=13, minute=0, second=0, microsecond=0))
        or (now > now.replace(hour=17, minute=0, second=0, microsecond=0)
            and now < now.replace(hour=18, minute=0, second=0, microsecond=0)))

    if condition:
        query = """SELECT DISTINCT ps.delivery_note, ps.name, ps.tracking_id
                FROM `tabPacking Slip` ps,`tabDelivery Note` dn WHERE ps.docstatus=1
                AND dn.docstatus=1 AND dn.is_manual_shipping = 0
                AND ps.tracking_status<>'Delivered' AND ps.delivery_note=dn.name"""

        packing_slips = frappe.db.sql(query, as_dict=True)

        for ps in packing_slips:
            status = get_package_tracking_status(ps.get("tracking_id"))
            # status = get_package_tracking_status("5932428095")
            # status = get_package_tracking_status("990728071")                 # In Transit
            # status = get_package_tracking_status("1Z12345E0291980793")        # Delivered

            if status:
                code = status.get("code")
                # update status
                ps_name = ps.get("name")
                description = status.get("description").capitalize()
                query = """UPDATE `tabPacking Slip` SET tracking_status='%s'
                        WHERE name='%s'""" % (description, ps_name)
                frappe.db.sql(query)
                query = """UPDATE `tabPacking Slip Details` SET tracking_status='%s'
                        WHERE parent='%s' AND packing_slip='%s'""" % (
                    description, ps.get("delivery_note"), ps_name)
                frappe.db.sql(query)

                if code == "I":
                    si = make_sales_invoice(
                        source_name=ps.get("delivery_note"), target_doc=None)
                    si.save(ignore_permissions=True)
                    create_todo(si.name, ps.get("delivery_note"))
예제 #6
0
def track_packages():
    # track packages and update the status
    # get all the packing_slips name
    date_format = convert_user_date_format()
    now = dt.strptime(datetime_in_user_format(dt.now()), date_format)
    #scheduler_events should run on 8AM, 12PM, and 5PM
    condition = ((now > now.replace(hour=8, minute=0, second=0, microsecond=0) and
                now < now.replace(hour=9, minute=0, second=0, microsecond=0)) or
                (now > now.replace(hour=12, minute=0, second=0, microsecond=0) and
                now < now.replace(hour=13, minute=0, second=0, microsecond=0)) or
                (now > now.replace(hour=17, minute=0, second=0, microsecond=0) and
                now < now.replace(hour=18, minute=0, second=0, microsecond=0)))

    if condition:
        query = """SELECT DISTINCT ps.delivery_note, ps.name, ps.tracking_id
                FROM `tabPacking Slip` ps,`tabDelivery Note` dn WHERE ps.docstatus=1
                AND dn.docstatus=1 AND dn.is_manual_shipping = 0
                AND ps.tracking_status<>'Delivered' AND ps.delivery_note=dn.name"""

        packing_slips = frappe.db.sql(query,as_dict=True)

        for ps in packing_slips:
            status = get_package_tracking_status(ps.get("tracking_id"))
            # status = get_package_tracking_status("5932428095")
            # status = get_package_tracking_status("990728071")                 # In Transit
            # status = get_package_tracking_status("1Z12345E0291980793")        # Delivered

            if status:
                code = status.get("code")
                # update status
                ps_name = ps.get("name")
                description = status.get("description").capitalize()
                query = """UPDATE `tabPacking Slip` SET tracking_status='%s'
                        WHERE name='%s'"""%(description, ps_name)
                frappe.db.sql(query)
                query = """UPDATE `tabPacking Slip Details` SET tracking_status='%s'
                        WHERE parent='%s' AND packing_slip='%s'"""%(description,
                        ps.get("delivery_note"),ps_name)
                frappe.db.sql(query)

                if code == "I":
                    si = make_sales_invoice(source_name=ps.get("delivery_note"), target_doc=None)
                    si.save(ignore_permissions=True)
                    create_todo(si.name, ps.get("delivery_note"))
예제 #7
0
	def validate_return_reference_doc(self):
		"""validate item with reference doc"""
		ref = get_return_doc_and_details(self)

		if ref.doc:
			# validate docstatus
			if ref.doc.docstatus != 1:
				frappe.throw(_("{0} {1} must be submitted").format(ref.doc.doctype, ref.doc.name),
					frappe.InvalidStatusError)

			# update stock check
			if ref.doc.doctype == "Sales Invoice" and cint(ref.doc.update_stock) != 1:
				frappe.throw(_("'Update Stock' for Sales Invoice {0} must be set").format(ref.doc.name), NotUpdateStockError)

			# posting date check
			ref_posting_datetime = "%s %s" % (ref.doc.posting_date, ref.doc.posting_time or "00:00:00")
			this_posting_datetime = "%s %s" % (self.posting_date, self.posting_time)

			if get_datetime(ref_posting_datetime) < get_datetime(ref_posting_datetime):
				from frappe.utils.dateutils import datetime_in_user_format
				frappe.throw(_("Posting timestamp must be after {0}")
					.format(datetime_in_user_format(ref_posting_datetime)))

			stock_items = get_stock_items_for_return(ref.doc, ref.parentfields)
			already_returned_item_qty = self.get_already_returned_item_qty(ref.fieldname)

			for item in self.get("items"):
				# validate if item exists in the ref doc and that it is a stock item
				if item.item_code not in stock_items:
					frappe.throw(_("Item {0} does not exist in {1} {2}").format(item.item_code, ref.doc.doctype, ref.doc.name),
						frappe.DoesNotExistError)

				# validate quantity <= ref item's qty - qty already returned
				if self.purpose == "Purchase Return":
					ref_item_qty = sum([flt(d.qty)*flt(d.conversion_factor) for d in ref.doc.get({"item_code": item.item_code})])
				elif self.purpose == "Sales Return":
					ref_item_qty = sum([flt(d.qty) for d in ref.doc.get({"item_code": item.item_code})])
				returnable_qty = ref_item_qty - flt(already_returned_item_qty.get(item.item_code))
				if not returnable_qty:
					frappe.throw(_("Item {0} has already been returned").format(item.item_code), StockOverReturnError)
				elif item.transfer_qty > returnable_qty:
					frappe.throw(_("Cannot return more than {0} for Item {1}").format(returnable_qty, item.item_code),
						StockOverReturnError)
예제 #8
0
	def set_calendar_invite(self, part):
		from icalendar import Calendar, Event
		cal = Calendar.from_ical(self.get_payload(part))

		start_format = "%a %b %d %H:%M"
		end_format = "%H:%M"  # only hour needed for end time

		text_content = ""

		for component in cal.walk('vevent'):
			event = component.get('summary')
			description = component.get('description')
			location = component.get('location')
			end = component.get('dtend')
			from frappe.utils.dateutils import datetime_in_user_format
			start = datetime_in_user_format(component.get('dtstart').dt)
			total_time = "%s-%s" % (start, end.dt.strftime(end_format))

			text_content += "Calendar Invite\n\n Summary: %s \n\nDescription: %s \n\nLocation: %s \n\nTime: %s \n\n------\n\n " % (event, description, location, total_time)

		self.text_content += text_content
		self.html_content += markdown(text_content)