How to set a future Date in DocType?

Hello,

In my custom DocType I have a need where when a user selects Start Date the End Date should automatically get calculated. Here the rule is that End Date should always be 30 days after the Start Date.

Can I define such a rule at DocType level or have I to write custom script for this?

TIA

Yogi Yang

@YogiYang I think that you need a Client Script for that.

1 Like
const from_date = frappe.datetime.get_today();
const to_date = frappe.datetime.add_months(from_date, 1)

Wire this in your doctype’s client script somehow.

@ankush
Thanks for the code snippet.

I wrote this code in Client Script

planned_start_date:function(frm){
        const from_date = frm.planned_start_date;
        const to_date = frappe.datetime.add_days(from_date, 35);
        frm.planned_end_date = to_date
        frm.refresh_field('planned_end_date');
    }

But in brower which is FireFox I am getting following Console dump

Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
Arguments: 
[0] _isAMomentObject: true, _isUTC: true, _useUTC: true, _l: undefined, _i: undefined, _f: undefined, _strict: undefined, _locale: [object Object]
t/<@http://localhost:8004/assets/js/libs.min.js?ver=1658757213.0:231:3368
va@http://localhost:8004/assets/js/libs.min.js?ver=1658757213.0:231:21539
Sa@http://localhost:8004/assets/js/libs.min.js?ver=1658757213.0:231:22250
c@http://localhost:8004/assets/js/libs.min.js?ver=1658757213.0:231:935
R@http://localhost:8004/assets/js/libs.min.js?ver=1658757213.0:234:3771
convert_to_user_tz@http://localhost:8004/assets/js/desk.min.js?ver=1658757213.0:17626:27
prettyDate@http://localhost:8004/assets/js/desk.min.js?ver=1658757213.0:12405:27
frappe.datetime.refresh_when/<@http://localhost:8004/assets/js/desk.min.js?ver=1658757213.0:12486:18
each@http://localhost:8004/assets/frappe/js/lib/jquery/jquery.min.js:2:2861
each@http://localhost:8004/assets/frappe/js/lib/jquery/jquery.min.js:2:845
frappe.datetime.refresh_when@http://localhost:8004/assets/js/desk.min.js?ver=1658757213.0:12485:27
@http://localhost:8004/assets/js/desk.min.js?ver=1658757213.0:12492:19

The date is not getting set in the target field.

TIA

Yogi Yang

@YogiYang This error happens because the values of planned_start_date is a string and the first param required by add_days must be a date object so you must convert the date string to object by using frappe.datetime.str_to_obj or Date.parse.

planned_start_date: function(frm) {
    const from_date = frappe.datetime.str_to_obj(frm.doc.planned_start_date);
    //const from_date = Date.parse(frm.doc.planned_start_date);
    const to_date = frappe.datetime.add_days(from_date, 35);
    frm.doc.planned_end_date = to_date
    frm.refresh_field('planned_end_date');
}

@kid1194,

I am still getting the same Warning in Console and planned_end_date remains empty.

TIA

Yogi Yang

@YogiYang How about we use a vanilla way.

planned_start_date: function(frm) {
    if (!frm.doc.planned_start_date) return;
    const from_date = new Date(frm.doc.planned_start_date);
    from_date.setDate(from_date.getDate() + 35);
    frm.doc.planned_end_date = frappe.datetime.obj_to_str(from_date);
    // Remove if no longer needed
    console.log(frm.doc.planned_start_date, frm.doc.planned_end_date);
    frm.refresh_field('planned_end_date');
}

I added some logs for you to see the start and end date.

@kid1194

I adapted your code to sales invoice:

frappe.ui.form.on('Sales Invoice', {
	posting_date: function(frm) {
	  const posting_date = new Date(frm.doc.posting_date);
	  posting_date.setDate(posting_date.getDate() + 30);
	  frm.doc.due_date = frappe.datetime.obj_to_str(posting_date);
	  console.log(frm.doc.posting_date, frm.doc.due_date)
	  frm.refresh_field('due_date')
	}
})

While I see that the Due Date changes, for some reason it reverts back to the standard date immediately. I am at a loss as to why this is happening as there’s no error. Can you help identify the issue?

Thanks.

@flexy2ky How about you try using this better code…

This code will update the due date everytime the posting date changes…

And hopefully this time the due date will not revert back to default value…

frappe.ui.form.on('Sales Invoice', {
    refresh: function(frm) {
        if (frm.is_new()) update_due_date(frm);
    },
    posting_date: function(frm) {
        update_due_date(frm);
    },
});
function update_due_date(frm) {
    let posting_date = frm.doc.posting_date;
    if (!posting_date) {
        frm.set_value('due_date', '');
        return;
    }
    let date_obj = new Date(posting_date);
    date_obj.setDate(date_obj.getDate() + 30);
    frm.set_value('due_date', frappe.datetime.obj_to_str(date_obj));
}
3 Likes

Outstanding! This works. Thanks a bunch