Пример #1
0
    def get_doc(start_idx):
        if doctypes:
            doc = {}
            for idx in xrange(start_idx, len(rows)):
                if (not doc) or main_doc_empty(rows[idx]):
                    for dt in doctypes:
                        d = {}
                        for column_idx in column_idx_to_fieldname[dt]:
                            try:
                                fieldname = column_idx_to_fieldname[dt][
                                    column_idx]
                                fieldtype = column_idx_to_fieldtype[dt][
                                    column_idx]

                                d[fieldname] = rows[idx][column_idx]
                                if fieldtype in ("Int", "Check"):
                                    d[fieldname] = cint(d[fieldname])
                                elif fieldtype in ("Float", "Currency",
                                                   "Percent"):
                                    d[fieldname] = flt(d[fieldname])
                                elif fieldtype == "Date":
                                    d[fieldname] = getdate(
                                        parse_date(d[fieldname])
                                    ) if d[fieldname] else None
                                elif fieldtype == "Datetime":
                                    if d[fieldname]:
                                        _date, _time = d[fieldname].split()
                                        _date = parse_date(d[fieldname])
                                        d[fieldname] = get_datetime(_date +
                                                                    " " +
                                                                    _time)
                                    else:
                                        d[fieldname] = None
                            except IndexError:
                                pass

                        # scrub quotes from name and modified
                        if d.get("name") and d["name"].startswith('"'):
                            d["name"] = d["name"][1:-1]

                        if sum([0 if not val else 1 for val in d.values()]):
                            d['doctype'] = dt
                            if dt == doctype:
                                doc.update(d)
                            else:
                                if not overwrite:
                                    d['parent'] = doc["name"]
                                d['parenttype'] = doctype
                                d['parentfield'] = doctype_parentfield[dt]
                                doc.setdefault(d['parentfield'], []).append(d)
                else:
                    break

            return doc
        else:
            doc = frappe._dict(zip(columns, rows[start_idx][1:]))
            doc['doctype'] = doctype
            return doc
Пример #2
0
def addrecords(name, datarows, limit=65000):
    meta = frappe.get_meta(name)
    columns = 0
    x = 0
    j = 0
    for row in datarows:
        if j >= limit: break
        if columns == 0:
            fields = row
            columns = len(fields)
            continue
        datadoc = {"doctype": name}
        i = 0
        for cell in row:
            if i >= columns: break
            df = meta.get_field(fields[i])
            fieldtype = df.fieldtype if df else "Data"
            if fieldtype in ("Int", "Check"):
                cell = cint(cell)
            elif fieldtype in ("Float", "Currency", "Percent"):
                cell = flt(cell)
            elif fieldtype == "Date":
                if cell and isinstance(cell, datetime):
                    cell = str(cell)
                if cell and isinstance(cell, string_types):
                    cell = getdate(parse_date(cell))
            elif fieldtype == "Datetime":
                if cell:
                    if " " in cell:
                        _date, _time = cell.split()
                    else:
                        _date, _time = cell, '00:00:00'
                    _date = parse_date(cell)
                    cell = get_datetime(_date + " " + _time)
                else:
                    cell = None
            elif fieldtype in ("Link", "Dynamic Link", "Data") and cell:
                cell = cstr(cell)

            datadoc.setdefault(fields[i], cell)
            i += 1

        row_original = str(datadoc)
        xduplicates = frappe.get_list(name,
                                      filters={'row_original': row_original},
                                      fields=['name'])
        j += 1
        if len(xduplicates) > 0:
            x += 1
            continue
        datadoc = conversionrules(datadoc)
        datadoc.setdefault("row_original", row_original)
        doc = frappe.get_doc(datadoc)
        doc.insert(ignore_permissions=True)
    return j - x
Пример #3
0
	def get_doc(start_idx):
		if doctypes:
			doc = {}
			for idx in xrange(start_idx, len(rows)):
				if (not doc) or main_doc_empty(rows[idx]):
					for dt, parentfield in doctypes:
						d = {}
						for column_idx in column_idx_to_fieldname[(dt, parentfield)]:
							try:
								fieldname = column_idx_to_fieldname[(dt, parentfield)][column_idx]
								fieldtype = column_idx_to_fieldtype[(dt, parentfield)][column_idx]

								d[fieldname] = rows[idx][column_idx]
								if fieldtype in ("Int", "Check"):
									d[fieldname] = cint(d[fieldname])
								elif fieldtype in ("Float", "Currency", "Percent"):
									d[fieldname] = flt(d[fieldname])
								elif fieldtype == "Date":
									d[fieldname] = getdate(parse_date(d[fieldname])) if d[fieldname] else None
								elif fieldtype == "Datetime":
									if d[fieldname]:
										if " " in d[fieldname]:
											_date, _time = d[fieldname].split()
										else:
											_date, _time = d[fieldname], '00:00:00'
										_date = parse_date(d[fieldname])
										d[fieldname] = get_datetime(_date + " " + _time)
									else:
										d[fieldname] = None
							except IndexError:
								pass

						# scrub quotes from name and modified
						if d.get("name") and d["name"].startswith('"'):
							d["name"] = d["name"][1:-1]

						if sum([0 if not val else 1 for val in d.values()]):
							d['doctype'] = dt
							if dt == doctype:
								doc.update(d)
							else:
								if not overwrite:
									d['parent'] = doc["name"]
								d['parenttype'] = doctype
								d['parentfield'] = parentfield
								doc.setdefault(d['parentfield'], []).append(d)
				else:
					break

			return doc
		else:
			doc = frappe._dict(zip(columns, rows[start_idx][1:]))
			doc['doctype'] = doctype
			return doc
Пример #4
0
def update_or_create_item_discount(site_name, doc_item, oc_discount, save=False, is_updating=False):
    disc_template = '{customer_group_id}-{quantity}-{priority}-{date_start}-{date_end}'

    oc_discount_copy = dict(oc_discount)
    oc_discount_copy.update({
        'date_start': parse_date(str(oc_discount.get('date_start'))) if oc_discount.get('date_start') else '',
        'date_end': parse_date(str(oc_discount.get('date_end'))) if oc_discount.get('date_end') else ''
    })
    oc_discount_hash = disc_template.format(**oc_discount_copy)
    # frappe.msgprint('items::update_or_create_item_discount')
    for doc_oc_discount in doc_item.get('oc_discounts'):
        if site_name != doc_oc_discount.get('oc_site'):
            continue
        doc_customer_group = frappe.get_doc('Customer Group', doc_oc_discount.get('customer_group'))
        if site_name != doc_customer_group.get('oc_site'):
            continue
        customer_group_id = doc_customer_group.get('oc_customer_group_id')
        if not customer_group_id:
            frappe.throw('customer_group_id is not set in Customer Group "%s"' % doc_oc_discount.get('customer_group'))
        doc_discount_hash = disc_template.format(**{
            'customer_group_id': customer_group_id,
            # 'price': doc_oc_discount.get('price'),
            'priority': int(doc_oc_discount.get('priority', 0)),
            'quantity': int(doc_oc_discount.get('quantity', 0)),
            'date_start': parse_date(str(doc_oc_discount.get('date_start'))) if doc_oc_discount.get('date_start') else '',
            'date_end': parse_date(str(doc_oc_discount.get('date_end'))) if doc_oc_discount.get('date_end') else '',
        })
        if oc_discount_hash == doc_discount_hash:
            doc_oc_discount.update({'price': oc_discount.get('price')})
            update_discount_prices(doc_oc_discount, oc_discount)
            doc_oc_discount.save()
            break
    else:
        doc_customer_group = customer_groups.get(site_name, oc_discount.get('customer_group_id'))
        if not doc_customer_group:
            frappe.throw('Cannot not found Customer Group with customer_group_id "%s" for Item "%s"' % (customer_group_id, doc_item.get('name')))
        doc_oc_discount = frappe.get_doc({
            'doctype': 'Opencart Discount',
            'oc_site': site_name,
            'item_name': doc_item.get('name'),
            'customer_group': doc_customer_group.get('name'),
            'quantity': oc_discount.get('quantity'),
            'priority': oc_discount.get('priority'),
            'price': oc_discount.get('price'),
            'date_start': oc_discount.get('date_start'),
            'date_end': oc_discount.get('date_end'),
        })
        update_discount_prices(doc_oc_discount, oc_discount)
        doc_item.append('oc_discounts', doc_oc_discount)
        if is_updating:
            doc_item.update({'oc_is_updating': 1})
        if save:
            doc_item.save()
Пример #5
0
    def reconcile_multiple_transactions_with_one_document(self):
        reconciled_amount = 0
        for bank_transaction in self.bank_transactions:
            if abs(self.documents[0]
                   ["unreconciled_amount"]) > reconciled_amount:
                bank_transaction = frappe.get_doc("Bank Transaction",
                                                  bank_transaction.get("name"))
                allocated_amount = min(
                    max(bank_transaction.unallocated_amount, 0),
                    abs(self.documents[0]["unreconciled_amount"]))
                date_value = self.documents[0].get("reference_date")
                if isinstance(date_value, str):
                    date_value = parse_date(date_value)

                if allocated_amount > 0:
                    bank_transaction.append(
                        'payment_entries', {
                            'payment_document':
                            self.reconciliation_doctype,
                            'payment_entry':
                            self.documents[0]["name"],
                            'allocated_amount':
                            allocated_amount,
                            'party':
                            self.documents[0][PARTY_FIELD.get(
                                self.reconciliation_doctype)],
                            'date':
                            getdate(date_value)
                        })

                    reconciled_amount += allocated_amount
                    bank_transaction.save()
Пример #6
0
def check_record(d, parenttype=None, doctype_dl=None):
	"""check for mandatory, select options, dates. these should ideally be in doclist"""
	from frappe.utils.dateutils import parse_date
	if parenttype and not d.get('parent'):
		frappe.msgprint(_("Parent is required."), raise_exception=1)

	if not doctype_dl:
		doctype_dl = frappe.model.doctype.get(d.doctype)

	for key in d:
		docfield = doctype_dl.get_field(key)
		val = d[key]
		if docfield:
			if docfield.reqd and (val=='' or val==None):
				frappe.msgprint("%s is mandatory." % docfield.label, raise_exception=1)

			if docfield.fieldtype=='Select' and val and docfield.options:
				if docfield.options.startswith('link:'):
					link_doctype = docfield.options.split(':')[1]
					if not frappe.db.exists(link_doctype, val):
						frappe.msgprint("%s: %s must be a valid %s" % (docfield.label, val, link_doctype), 
							raise_exception=1)
				elif docfield.options == "attach_files:":
					pass
					
				elif val not in docfield.options.split('\n'):
					frappe.msgprint("%s must be one of: %s" % (docfield.label, 
						", ".join(filter(None, docfield.options.split("\n")))), raise_exception=1)
					
			if val and docfield.fieldtype=='Date':
				d[key] = parse_date(val)
			elif val and docfield.fieldtype in ["Int", "Check"]:
				d[key] = cint(val)
			elif val and docfield.fieldtype in ["Currency", "Float"]:
				d[key] = flt(val)
Пример #7
0
def create_bank_entries(columns, data, bank_account):
    header_map = get_header_mapping(columns, bank_account)

    success = 0
    errors = 0
    for d in json.loads(data):
        if all(item is None for item in d) is True:
            continue
        fields = {}
        for key, value in iteritems(header_map):
            fields.update({key: d[int(value) - 1]})

        try:
            bank_transaction = frappe.get_doc({"doctype": "Bank Transaction"})
            bank_transaction.update(fields)
            bank_transaction.date = getdate(parse_date(bank_transaction.date))
            bank_transaction.bank_account = bank_account
            bank_transaction.insert()
            bank_transaction.submit()
            success += 1
        except Exception:
            frappe.log_error(frappe.get_traceback())
            errors += 1

    return {"success": success, "errors": errors}
Пример #8
0
def create_bank_entries(columns, data, bank_account):
	bank_name = frappe.db.get_value("Bank Account", bank_account, "bank")
	bank = frappe.get_doc("Bank", bank_name)
	header_map = get_header_mapping(columns, bank)

	success = 0
	errors = 0
	total = len(json.loads(data))
	for idx, d in enumerate(json.loads(data)):
		if all(item is None for item in d) is True:
			continue
		fields = {}
		for key, value in iteritems(header_map):
			fields.update({
				key: get_value(d, key, bank, int(value)-1)
			})

		frappe.publish_progress(((idx+1)*100)/total, title=_("Importing Transactions"),description=_("Transaction {0} of {1}.").format(idx, total))

		try:
			bank_transaction = frappe.get_doc({
				"doctype": "Bank Transaction"
			})
			bank_transaction.update(fields)
			bank_transaction.date = getdate(parse_date(bank_transaction.date))
			bank_transaction.bank_account = bank_account
			bank_transaction.insert()
			bank_transaction.submit()
			success += 1
		except Exception:
			frappe.log_error(frappe.get_traceback())
			errors += 1

	return {"success": success, "errors": errors}
Пример #9
0
def create_bank_entries(columns, data, bank_account):
	header_map = get_header_mapping(columns, bank_account)

	success = 0
	errors = 0
	for d in json.loads(data):
		if all(item is None for item in d) is True:
			continue
		fields = {}
		for key, value in iteritems(header_map):
			fields.update({key: d[int(value)-1]})

		try:
			bank_transaction = frappe.get_doc({
				"doctype": "Bank Transaction"
			})
			bank_transaction.update(fields)
			bank_transaction.date = getdate(parse_date(bank_transaction.date))
			bank_transaction.bank_account = bank_account
			bank_transaction.insert()
			bank_transaction.submit()
			success += 1
		except Exception:
			frappe.log_error(frappe.get_traceback())
			errors += 1

	return {"success": success, "errors": errors}
Пример #10
0
def check_record(d):
    """check for mandatory, select options, dates. these should ideally be in doclist"""
    from frappe.utils.dateutils import parse_date
    doc = frappe.get_doc(d)
    frappe.errprint(type(d))
    for key in d:
        docfield = doc.meta.get_field(key)
        val = d[key]
        if docfield:
            if docfield.reqd and (val == '' or val == None):
                frappe.msgprint(_("{0} is required").format(docfield.label),
                                raise_exception=1)

            if docfield.fieldtype == 'Select' and val and docfield.options:
                if docfield.options.startswith('link:'):
                    link_doctype = docfield.options.split(':')[1]
                    if not frappe.db.exists(link_doctype, val):
                        frappe.throw(
                            _("{0} {1} must be a valid {2}").format(
                                _(docfield.lable), val, _(link_doctype)))
                elif docfield.options == "attach_files:":
                    pass

                elif val not in docfield.options.split('\n'):
                    frappe.throw(
                        _("{0} must be one of {1}").format(
                            _(docfield.label),
                            comma_or(docfield.options.split("\n"))))

            if val and docfield.fieldtype == 'Date':
                d[key] = parse_date(val)
            elif val and docfield.fieldtype in ["Int", "Check"]:
                d[key] = cint(val)
            elif val and docfield.fieldtype in ["Currency", "Float"]:
                d[key] = flt(val)
Пример #11
0
    def reconcile_created_payments(self):
        for transaction, payment in zip(self.bank_transactions,
                                        self.payment_entries):
            bank_transaction = frappe.get_doc("Bank Transaction",
                                              transaction.get("name"))
            date_value = payment.get("reference_date")
            if isinstance(date_value, str):
                date_value = parse_date(date_value)

            bank_transaction.append(
                'payment_entries', {
                    'payment_document':
                    payment.get("doctype"),
                    'payment_entry':
                    payment.get("name"),
                    'allocated_amount':
                    min(abs(payment.get("unreconciled_amount")),
                        abs(bank_transaction.unallocated_amount)),
                    'party':
                    payment.get(PARTY_FIELD.get(payment.get("doctype"))),
                    'date':
                    getdate(date_value)
                })

            bank_transaction.save()
Пример #12
0
def check_record(d):
    """check for mandatory, select options, dates. these should ideally be in doclist"""
    from frappe.utils.dateutils import parse_date
    doc = frappe.get_doc(d)

    for key in d:
        docfield = doc.meta.get_field(key)
        val = d[key]
        if docfield:
            if docfield.reqd and (val == '' or val == None):
                frappe.msgprint(_("{0} is required").format(docfield.label),
                                raise_exception=1)

            if docfield.fieldtype == 'Select' and val and docfield.options:
                if val not in docfield.options.split('\n'):
                    frappe.throw(
                        _("{0} must be one of {1}").format(
                            _(docfield.label),
                            comma_or(docfield.options.split("\n"))))

            if val and docfield.fieldtype == 'Date':
                d[key] = parse_date(val)
            elif val and docfield.fieldtype in ["Int", "Check"]:
                d[key] = cint(val)
            elif val and docfield.fieldtype in [
                    "Currency", "Float", "Percent"
            ]:
                d[key] = flt(val)
Пример #13
0
def check_record(d):
	"""check for mandatory, select options, dates. these should ideally be in doclist"""
	from frappe.utils.dateutils import parse_date
	doc = frappe.get_doc(d)

	for key in d:
		docfield = doc.meta.get_field(key)
		val = d[key]
		if docfield:
			if docfield.reqd and (val=='' or val==None):
				frappe.msgprint(_("{0} is required").format(docfield.label), raise_exception=1)

			if docfield.fieldtype=='Select' and val and docfield.options:
				if docfield.options == "attach_files:":
					pass

				elif val not in docfield.options.split('\n'):
					frappe.throw(_("{0} must be one of {1}").format(_(docfield.label), comma_or(docfield.options.split("\n"))))

			if val and docfield.fieldtype=='Date':
				d[key] = parse_date(val)
			elif val and docfield.fieldtype in ["Int", "Check"]:
				d[key] = cint(val)
			elif val and docfield.fieldtype in ["Currency", "Float", "Percent"]:
				d[key] = flt(val)
Пример #14
0
def create_oauth_user(data, provider):
    if data.get("birthday"):
        from frappe.utils.dateutils import parse_date
        data["birthday"] = parse_date(data["birthday"])

    if isinstance(data.get("location"), dict):
        data["location"] = data.get("location").get("name")

    user = frappe.get_doc({
        "doctype":
        "User",
        "first_name":
        data.get("first_name") or data.get("given_name") or data.get("name"),
        "last_name":
        data.get("last_name") or data.get("family_name"),
        "email":
        data["email"],
        "gender":
        data.get("gender"),
        "enabled":
        1,
        "new_password":
        frappe.generate_hash(data["email"]),
        "location":
        data.get("location"),
        "birth_date":
        data.get("birthday"),
        "user_type":
        "Website User",
        "user_image":
        data.get("picture") or data.get("avatar_url")
    })

    if provider == "facebook":
        user.update({
            "fb_username":
            data["username"],
            "fb_userid":
            data["id"],
            "user_image":
            "https://graph.facebook.com/{username}/picture".format(
                username=data["username"])
        })
    elif provider == "google":
        user.google_userid = data["id"]

    elif provider == "github":
        user.github_userid = data["id"]
        user.github_username = data["login"]

    user.ignore_permissions = True
    user.no_welcome_mail = True
    user.insert()
Пример #15
0
def create_bank_entries(columns, data, bank_account, upload_type=None):
    if not upload_type:
        frappe.throw(_("Please upload a file first"))

    header_map = get_header_mapping(columns, bank_account, upload_type)
    if not header_map:
        return {"status": "Missing header map"}

    success = 0
    errors = 0
    duplicates = 0
    for d in json.loads(data):
        if all(item is None for item in d) is True:
            continue
        fields = {}
        for key, dummy in iteritems(header_map):
            fields.update({header_map.get(key): d.get(key)})

        try:
            bank_transaction = frappe.new_doc("Bank Transaction")
            bank_transaction.update(fields)
            bank_transaction.date = getdate(parse_date(bank_transaction.date))
            bank_transaction.bank_account = bank_account
            bank_transaction.flags.import_statement = True
            bank_transaction.insert()
            bank_transaction.submit()
            success += 1
            frappe.db.commit()
        except frappe.UniqueValidationError:
            duplicates += 1
            frappe.clear_messages()

        except frappe.DuplicateEntryError:
            duplicates += 1
            frappe.clear_messages()

        except Exception:
            errors += 1
            frappe.log_error(frappe.get_traceback(),
                             _("Bank transaction creation error"))

    return {
        "success": success,
        "errors": errors,
        "duplicates": duplicates,
        "status": "Complete"
    }
Пример #16
0
def create_bank_entries(columns, data, bank_account):
    header_map = get_header_mapping(columns, bank_account)

    count = 0
    for d in json.loads(data):
        if all(item is None for item in d) is True:
            continue
        fields = {}
        for key, value in iteritems(header_map):
            fields.update({key: d[int(value) - 1]})

        bank_transaction = frappe.get_doc({"doctype": "Bank Transaction"})
        bank_transaction.update(fields)
        bank_transaction.date = getdate(parse_date(bank_transaction.date))
        bank_transaction.bank_account = bank_account
        bank_transaction.insert()
        bank_transaction.submit()
        count = count + 1

    return count
Пример #17
0
	def validate(self):
		if not self.lot:
			frappe.throw(_("Lot number is not generated. Please contact your admin."))

		veh_ref_cp = []
		for veh_ref in self.vehicle_reference:
			if veh_ref.date > nowdate():
				frappe.throw(_("Date entered cannot be greater than today's date"))
			diff = frappe.utils.date_diff(nowdate(), veh_ref.date)
			if diff > 30 and not self.confirm_days_old:
				frappe.throw(_("Days Old {0} is greater than 30 days. Check Confirm Days Old to confirm.").format(diff))
			date_str = dateutils.parse_date(veh_ref.date)
			year = date_str[2:4]
			month = date_str[5:7]
			day = date_str[8:11]
			veh_ref.vehicle_reference = year + month + day + "." + veh_ref.truck_sequence + veh_ref.species_sequence
			veh_ref_cp.append({
				'vehicle_reference': veh_ref.vehicle_reference,
				'date': veh_ref.date,
				'truck_sequence': veh_ref.truck_sequence,
				'species_sequence': veh_ref.species_sequence
						})

		duplicates = [ref for n, ref in enumerate(veh_ref_cp) if ref in veh_ref_cp[:n]]
		if duplicates:
			frappe.throw(_("Duplicates exist for Date, TT and SS combination"))

		if self.sort_order == "Ascending":
			sort_order = False
		else:
			sort_order = True
		veh_ref_cp = sorted(veh_ref_cp,key=itemgetter('vehicle_reference'),reverse=sort_order)
		self.vehicle_reference = []
		for ref in veh_ref_cp:
			self.append('vehicle_reference',
			{'date': ref["date"],
			'truck_sequence': ref["truck_sequence"],
			'species_sequence': ref["species_sequence"],
			'vehicle_reference': ref["vehicle_reference"]})
Пример #18
0
def create_oauth_user(data, provider):
	if data.get("birthday"):
		from frappe.utils.dateutils import parse_date
		data["birthday"] = parse_date(data["birthday"])

	if isinstance(data.get("location"), dict):
		data["location"] = data.get("location").get("name")

	user = frappe.get_doc({
		"doctype":"User",
		"first_name": data.get("first_name") or data.get("given_name") or data.get("name"),
		"last_name": data.get("last_name") or data.get("family_name"),
		"email": data["email"],
		"gender": data.get("gender"),
		"enabled": 1,
		"new_password": frappe.generate_hash(data["email"]),
		"location": data.get("location"),
		"birth_date":  data.get("birthday"),
		"user_type": "Website User",
		"user_image": data.get("picture") or data.get("avatar_url")
	})

	if provider=="facebook":
		user.update({
			"fb_username": data["username"],
			"fb_userid": data["id"],
			"user_image": "https://graph.facebook.com/{username}/picture".format(username=data["username"])
		})
	elif provider=="google":
		user.google_userid = data["id"]

	elif provider=="github":
		user.github_userid = data["id"]
		user.github_username = data["login"]

	user.ignore_permissions = True
	user.no_welcome_mail = True
	user.insert()
Пример #19
0
    def check_matching_dates(self, output):
        if not output:
            return []

        comparison_date = self.bank_transactions[0].get("date")
        description = self.bank_transactions[0].get("description")

        output = sorted(output,
                        key=lambda doc: difflib.SequenceMatcher(
                            lambda doc: doc == " ", str(doc.get("party")),
                            description).ratio(),
                        reverse=True)

        date_field = self.get_reference_date_field()
        closest = min(output[:10],
                      key=lambda x: abs(
                          getdate(x.get(date_field)) - getdate(
                              parse_date(comparison_date))))

        return [
            dict(x, **{"vgtSelected": True})
            if x.get("name") == closest.get("name") else x for x in output
        ]
Пример #20
0
def create_bank_entries(columns, data, bank_account):
	header_map = get_header_mapping(columns, bank_account)

	count = 0
	for d in json.loads(data):
		if all(item is None for item in d) is True:
			continue
		fields = {}
		for key, value in header_map.iteritems():
			fields.update({key: d[int(value)-1]})


		bank_transaction = frappe.get_doc({
			"doctype": "Bank Transaction"
		})
		bank_transaction.update(fields)
		bank_transaction.date = getdate(parse_date(bank_transaction.date))
		bank_transaction.bank_account = bank_account
		bank_transaction.insert()
		bank_transaction.submit()
		count = count + 1

	return count
Пример #21
0
    def reconcile_one_transaction_with_multiple_documents(self):
        for document in self.documents:
            bank_transaction = frappe.get_doc(
                "Bank Transaction", self.bank_transactions[0]["name"])
            date_value = document.get("reference_date")
            if isinstance(date_value, str):
                date_value = parse_date(date_value)

            if flt(bank_transaction.unallocated_amount) != 0:
                bank_transaction.append(
                    'payment_entries', {
                        'payment_document':
                        document.get("doctype"),
                        'payment_entry':
                        document.get("name"),
                        'allocated_amount':
                        abs(document.get("unreconciled_amount")),
                        'party':
                        document.get(PARTY_FIELD.get(document.get("doctype"))),
                        'date':
                        getdate(date_value)
                    })

                bank_transaction.save()
Пример #22
0
    def get_doc(start_idx):
        if doctypes:
            doc = {}
            attachments = []
            last_error_row_idx = None
            for idx in range(start_idx, len(rows)):
                last_error_row_idx = idx  # pylint: disable=W0612
                if (not doc) or main_doc_empty(rows[idx]):
                    for dt, parentfield in doctypes:
                        d = {}
                        for column_idx in column_idx_to_fieldname[(
                                dt, parentfield)]:
                            try:
                                fieldname = column_idx_to_fieldname[(
                                    dt, parentfield)][column_idx]
                                fieldtype = column_idx_to_fieldtype[(
                                    dt, parentfield)][column_idx]

                                if not fieldname or not rows[idx][column_idx]:
                                    continue

                                d[fieldname] = rows[idx][column_idx]
                                if fieldtype in ("Int", "Check"):
                                    d[fieldname] = cint(d[fieldname])
                                elif fieldtype in ("Float", "Currency",
                                                   "Percent"):
                                    d[fieldname] = flt(d[fieldname])
                                elif fieldtype == "Date":
                                    if d[fieldname] and isinstance(
                                            d[fieldname], string_types):
                                        d[fieldname] = getdate(
                                            parse_date(d[fieldname]))
                                elif fieldtype == "Datetime":
                                    if d[fieldname]:
                                        if " " in d[fieldname]:
                                            _date, _time = d[fieldname].split()
                                        else:
                                            _date, _time = d[
                                                fieldname], '00:00:00'
                                        _date = parse_date(d[fieldname])
                                        d[fieldname] = get_datetime(_date +
                                                                    " " +
                                                                    _time)
                                    else:
                                        d[fieldname] = None

                                elif fieldtype in ("Image", "Attach Image",
                                                   "Attach"):
                                    # added file to attachments list
                                    attachments.append(d[fieldname])

                                elif fieldtype in ("Link", "Dynamic Link",
                                                   "Data") and d[fieldname]:
                                    # as fields can be saved in the number format(long type) in data import template
                                    d[fieldname] = cstr(d[fieldname])

                            except IndexError:
                                pass

                        # scrub quotes from name and modified
                        if d.get("name") and d["name"].startswith('"'):
                            d["name"] = d["name"][1:-1]

                        if sum([0 if not val else 1 for val in d.values()]):
                            d['doctype'] = dt
                            if dt == doctype:
                                doc.update(d)
                            else:
                                if not overwrite and doc.get("name"):
                                    d['parent'] = doc["name"]
                                d['parenttype'] = doctype
                                d['parentfield'] = parentfield
                                doc.setdefault(d['parentfield'], []).append(d)
                else:
                    break
            #frappe.msgprint(doc)
            return doc, attachments, last_error_row_idx
        else:
            doc = frappe._dict(zip(columns, rows[start_idx][1:]))
            doc['doctype'] = doctype
            return doc, [], None
Пример #23
0
	def get_doc(start_idx):
		if doctypes:
			doc = {}
			attachments = []
			last_error_row_idx = None
			for idx in range(start_idx, len(rows)):
				last_error_row_idx = idx	# pylint: disable=W0612
				if (not doc) or main_doc_empty(rows[idx]):
					for dt, parentfield in doctypes:
						d = {}
						for column_idx in column_idx_to_fieldname[(dt, parentfield)]:
							try:
								fieldname = column_idx_to_fieldname[(dt, parentfield)][column_idx]
								fieldtype = column_idx_to_fieldtype[(dt, parentfield)][column_idx]

								if not fieldname or not rows[idx][column_idx]:
									continue

								d[fieldname] = rows[idx][column_idx]
								if fieldtype in ("Int", "Check"):
									d[fieldname] = cint(d[fieldname])
								elif fieldtype in ("Float", "Currency", "Percent"):
									d[fieldname] = flt(d[fieldname])
								elif fieldtype == "Date":
									if d[fieldname] and isinstance(d[fieldname], string_types):
										d[fieldname] = getdate(parse_date(d[fieldname]))
								elif fieldtype == "Datetime":
									if d[fieldname]:
										if " " in d[fieldname]:
											_date, _time = d[fieldname].split()
										else:
											_date, _time = d[fieldname], '00:00:00'
										_date = parse_date(d[fieldname])
										d[fieldname] = get_datetime(_date + " " + _time)
									else:
										d[fieldname] = None

								elif fieldtype in ("Image", "Attach Image", "Attach"):
									# added file to attachments list
									attachments.append(d[fieldname])

								elif fieldtype in ("Link", "Dynamic Link", "Data") and d[fieldname]:
									# as fields can be saved in the number format(long type) in data import template
									d[fieldname] = cstr(d[fieldname])

							except IndexError:
								pass

						# scrub quotes from name and modified
						if d.get("name") and d["name"].startswith('"'):
							d["name"] = d["name"][1:-1]

						if sum([0 if not val else 1 for val in d.values()]):
							d['doctype'] = dt
							if dt == doctype:
								doc.update(d)
							else:
								if not overwrite and doc.get("name"):
									d['parent'] = doc["name"]
								d['parenttype'] = doctype
								d['parentfield'] = parentfield
								doc.setdefault(d['parentfield'], []).append(d)
				else:
					break

			return doc, attachments, last_error_row_idx
		else:
			doc = frappe._dict(zip(columns, rows[start_idx][1:]))
			doc['doctype'] = doctype
			return doc, [], None
Пример #24
0
def upload(import_settings=None):
    if not frappe.has_permission("Attendance", "create"):
        raise frappe.PermissionError

    from frappe.utils.csvutils import read_csv_content_from_uploaded_file
    from frappe.modules import scrub

    rows = read_csv_content_from_uploaded_file()
    rows = list(filter(lambda x: x and any(x), rows))
    if not rows:
        msg = [_("Please select a csv file")]
        return {"messages": msg, "error": msg}
    #fixme error when importing certain header
    #columns = [scrub(f) for f in rows[0]]

    columns = ["employee", "attendance_date", "arrival_time", "departure_time"]

    ret = []
    error = False
    started = False

    import json
    params = json.loads(frappe.form_dict.get("params") or '{}')

    if not params.get("import_settings"):
        import_settings = "default"
    else:
        import_settings = params.get("import_settings")

    from frappe.utils.csvutils import check_record, import_doc

    for i, row in enumerate(rows[1:]):
        if not row: continue
        started = True
        row_idx = i + 1
        d = frappe._dict(zip(columns, row))

        d["doctype"] = "Attendance"

        date_error = False
        try:
            parse_date(d.attendance_date)
        except Exception as e:
            date_error = True
            ret.append('Error for row (#%d) %s : %s' %
                       (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e)))
        except ValueError as e:
            date_error = True
            ret.append('Error for row (#%d) %s : %s' %
                       (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e)))
        except:
            date_error = True
            ret.append('Error for row (#%d) %s' %
                       (row_idx + 1, len(row) > 1 and row[1] or ""))

        if date_error == True:
            if import_settings != "ignore":
                error = True
            continue

        formatted_attendance_date = getdate(parse_date(d.attendance_date))

        if import_settings == "ignore":
            attendance = frappe.db.sql(
                """select name,docstatus,attendance_date from `tabAttendance` where employee = %s and attendance_date = %s""",
                (d.employee, formatted_attendance_date),
                as_dict=True)
            if attendance:
                link = [
                    '<a href="#Form/Attendance/{0}">{0}</a>'.format(
                        str(attendance[0].name))
                ]

                # ret.append('Ignored row (#%d) %s : %s - %s' % (row_idx+1,
                # len(row)>1 and row[1] or "", cstr(d.employee),link))
            else:
                try:
                    check_record(d)
                    ret.append(
                        import_doc(d, "Attendance", 1, row_idx, submit=False))
                except Exception, e:
                    # error = True
                    ret.append(
                        'Error for row (#%d) %s : %s' %
                        (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e)))
                    # frappe.errprint(frappe.get_traceback())

        elif import_settings == "update":
            attendance = frappe.db.sql(
                """select name,docstatus,attendance_date from `tabAttendance` where employee = %s and attendance_date = %s""",
                (d.employee, formatted_attendance_date),
                as_dict=True)

            if attendance:
                d["docstatus"] = attendance[0].docstatus
                d["name"] = attendance[0].name

            try:
                check_record(d)
                ret.append(
                    import_doc(d, "Attendance", 1, row_idx, submit=False))
            except Exception, e:
                error = True
                ret.append(
                    'Error for row (#%d) %s : %s' %
                    (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e)))
Пример #25
0
    def get_payment_entry(self, transaction):
        company_currency = frappe.db.get_value("Company", self.company,
                                               "default_currency")
        party_account_currency = get_account_currency(self.party_account)

        # payment type
        if (self.reconciliation_doctype == "Sales Invoice" and transaction.get("amount") > 0) \
         or (self.reconciliation_doctype == "Purchase Invoice" and transaction.get("amount") > 0):
            payment_type = "Receive"
        else:
            payment_type = "Pay"

        # total outstanding
        total_outstanding_amount = 0
        if self.reconciliation_doctype in ("Sales Invoice",
                                           "Purchase Invoice"):
            total_outstanding_amount = sum(
                [x.get("outstanding_amount") for x in self.documents])
        elif self.reconciliation_doctype in ("Expense Claim"):
            total_outstanding_amount = sum([
                (flt(x.get("grand_total")) -
                 flt(x.get("total_amount_reimbursed"))) for x in self.documents
            ])
        elif self.reconciliation_doctype == "Employee Advance":
            total_outstanding_amount = sum([
                (flt(x.get("advance_amount")) - flt(x.get("paid_amount")))
                for x in self.documents
            ])

        bank_account = frappe.get_doc("Bank Account",
                                      transaction.get("bank_account"))
        account_currency = frappe.db.get_value("Account", bank_account.account,
                                               "account_currency")

        paid_amount = received_amount = 0
        outstanding_amount = sum(
            [x.get("outstanding_amount") for x in self.documents])
        amount_to_pay_or_receive = abs(transaction.get("unallocated_amount")) \
          if abs(transaction.get("unallocated_amount")) <= outstanding_amount else outstanding_amount
        if party_account_currency == account_currency:
            paid_amount = received_amount = amount_to_pay_or_receive
        elif payment_type == "Receive":
            paid_amount = amount_to_pay_or_receive
            target_exchange_rate = total_outstanding_amount / paid_amount
            received_amount = total_outstanding_amount
        else:
            received_amount = amount_to_pay_or_receive
            source_exchange_rate = received_amount / total_outstanding_amount
            paid_amount = total_outstanding_amount

        pe = frappe.new_doc("Payment Entry")
        pe.payment_type = payment_type
        pe.company = bank_account.company
        pe.cost_center = self.cost_center
        pe.posting_date = getdate(parse_date(transaction.get("date")))
        pe.mode_of_payment = self.mode_of_payment
        pe.party_type = self.party_type
        pe.party = self.party
        contacts = [x.get("contact_person") for x in self.documents]
        pe.contact_person = contacts[0] if contacts else None
        pe.contact_email = " ,".join([
            x.get("contact_email") for x in self.documents
            if x.get("contact_email")
        ])
        pe.ensure_supplier_is_not_blocked()

        pe.paid_from = self.party_account if payment_type == "Receive" else bank_account.account
        pe.paid_to = self.party_account if payment_type == "Pay" else bank_account.account
        pe.paid_from_account_currency = party_account_currency \
         if payment_type == "Receive" else account_currency
        pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else account_currency
        pe.paid_amount = paid_amount
        pe.received_amount = received_amount
        letter_heads = [x.get("letter_head") for x in self.documents]
        pe.letter_head = letter_heads[0] if letter_heads else None
        pe.reference_no = transaction.get(
            "reference_number") or transaction.get("name")
        pe.reference_date = getdate(parse_date(transaction.get("date")))
        pe.bank_account = bank_account.name

        if pe.party_type in ["Customer", "Supplier"]:
            bank_account = get_party_bank_account(pe.party_type, pe.party)
            pe.set("party_bank_account", bank_account)
        pe.set_bank_account_data()

        total_allocated_amount = 0
        for doc in self.documents:
            # only Purchase Invoice can be blocked individually
            if doc.get("doctype") == "Purchase Invoice":
                pi = frappe.get_doc("Purchase Invoice", doc.get("name"))
                if pi.invoice_is_blocked():
                    frappe.throw(
                        _('{0} is on hold till {1}'.format(
                            pi.name, pi.release_date)))

            # amounts
            grand_total = outstanding_amount = 0
            if self.reconciliation_doctype in ("Sales Invoice",
                                               "Purchase Invoice"):
                if party_account_currency == doc.get("company_currency"):
                    grand_total = doc.get("base_rounded_total") or doc.get(
                        "base_grand_total")
                else:
                    grand_total = doc.get("rounded_total") or doc.get(
                        "grand_total")
                outstanding_amount = doc.get("outstanding_amount")
            elif self.reconciliation_doctype in ("Expense Claim"):
                grand_total = doc.get("total_sanctioned_amount") + doc.get(
                    "total_taxes_and_charges")
                outstanding_amount = doc.get("grand_total") - doc.get(
                    "total_amount_reimbursed")
            elif self.reconciliation_doctype == "Employee Advance":
                grand_total = doc.get("advance_amount")
                outstanding_amount = flt(doc.get("advance_amount")) - flt(
                    doc.get("paid_amount"))
            else:
                if party_account_currency == doc.get("company_currency"):
                    grand_total = flt(
                        doc.get("base_rounded_total")
                        or doc.get("base_grand_total"))
                else:
                    grand_total = flt(
                        doc.get("rounded_total") or doc.get("grand_total"))
                outstanding_amount = grand_total - flt(doc.get("advance_paid"))

            allocated_amount = min(
                outstanding_amount,
                flt(abs(transaction.get("unallocated_amount"))) -
                flt(total_allocated_amount))

            pe.append(
                "references", {
                    'reference_doctype': doc.get("doctype"),
                    'reference_name': doc.get("name"),
                    "bill_no": doc.get("bill_no"),
                    "due_date": doc.get("due_date"),
                    'total_amount': grand_total,
                    'outstanding_amount': outstanding_amount,
                    'allocated_amount': allocated_amount
                })

            total_allocated_amount += allocated_amount

        pe.setup_party_account_field()
        pe.set_missing_values()
        if self.party_account and bank_account:
            pe.set_exchange_rate()
            pe.set_amounts()
        return pe