public bool TinhToan(DateTime ngay, int ShiftID, TimeSpan ShiftWorkingTime, double ShiftWorkingDay, TimeSpan LunchMin,
                             DateTime ThoiDiem_onnDuty, DateTime ThoiDiem_offDuty, DateTime ThoiDiem_ChoPhepTre, DateTime ThoiDiem_ChoPhepSom,
                             DateTime timeBD, DateTime timeKT, int sophutOT, bool tinhPCTC,
                             out TimeSpan tongGioLam, out double cong, out double phucap)
        {
            var tongGioThuc = TimeSpan.Zero;

            tongGioLam = TimeSpan.Zero;
            cong       = 0f;
            phucap     = 0f;

            tongGioThuc = timeKT - timeBD;
            if (tongGioThuc < XL2._30phut || tongGioThuc > XL2._24h00)
            {
                MessageBox.Show("Thời gian vào ra chưa hợp lệ. Vui lòng kiểm tra lại.");
                return(false);
            }
            sophutOT = (checkXNLamThem.Checked && numSoPhutOT.Value > 0) ? (int)numSoPhutOT.Value : 0;
            if (ShiftID == int.MinValue)
            {
                ThoiDiem_onnDuty    = timeBD;
                ThoiDiem_offDuty    = timeBD.Add(XL2._08gio);
                ThoiDiem_ChoPhepTre = ThoiDiem_onnDuty.Add(XL2.ChoPhepTre);
                ThoiDiem_ChoPhepSom = ThoiDiem_offDuty.Subtract(XL2.ChoPhepSom);
            }
            if (ShiftID == int.MinValue + 1)
            {
                ThoiDiem_onnDuty    = timeBD;
                ThoiDiem_offDuty    = timeBD.Add(XL2._12gio);
                ThoiDiem_ChoPhepTre = ThoiDiem_onnDuty.Add(XL2.ChoPhepTre);
                ThoiDiem_ChoPhepSom = ThoiDiem_offDuty.Subtract(XL2.ChoPhepSom);
            }
            if (ThoiDiem_offDuty < timeBD || timeKT < ThoiDiem_onnDuty)
            {
                MessageBox.Show("Thời gian vào ra chưa hợp lệ. Vui lòng kiểm tra lại.");
                return(false);
            }
            var ra_coOT = ThoiDiem_offDuty.Add(new TimeSpan(0, sophutOT, 0));

            if (timeKT < ra_coOT && sophutOT > 0)
            {
                MessageBox.Show("Giờ ra chưa được cộng thêm giờ làm thêm. Vui lòng kiểm tra lại.");
                return(false);
            }

            var vaolam      = DateTime.MinValue;
            var raalam      = DateTime.MinValue;
            var raalam_CoOT = DateTime.MinValue;
            var vaotre      = TimeSpan.Zero;
            var raasom      = TimeSpan.Zero;

            XL.Vao(timeBD, ThoiDiem_onnDuty, ThoiDiem_ChoPhepTre, out vaolam, out vaotre);
            XL.Raa(timeKT, ThoiDiem_offDuty, ThoiDiem_ChoPhepSom, out raalam, out raasom);
            XL.LamThem(raalam, new TimeSpan(0, sophutOT, 0), out raalam_CoOT);
            tongGioLam = raalam_CoOT - vaolam - LunchMin;
            cong       = (tongGioLam.TotalHours / ShiftWorkingTime.TotalHours) * ShiftWorkingDay;
            phucap     = (tinhPCTC) ? ((tongGioLam > XL2._08gio) ? ((tongGioLam - XL2._08gio).TotalHours / 8d) * (XL2.PC50 / 100d) : 0d)
                                                                : 0f;

            return(true);
        }
        private void linkTinhLaiCong_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            DateTime td_batdau_lv, td_ketthuc_lv_chuaOT, td_ketthuc_lv_daCoOT, TD_BD_LV_Ca3, TD_KT_LV_Ca3;
            TimeSpan tre, som, treKoTruVR, somKoTruVR, tongGiothuc = TimeSpan.Zero, TGGioLamViec = TimeSpan.Zero, TGLamBanDem, tgTinhPC30, tgTinhPC50, tgTinhPCTCC3;
            float    Cong = 0f, PhuCap30, PhuCapTC, PhuCapTCC3, TongPhuCap = 0f;
            bool     QuaDem;
            var      ngay       = DateTime.Today;
            TimeSpan timespanBD = dtpBDLam.Value.TimeOfDay;
            TimeSpan timeSpanKT = dtpKTLam.Value.TimeOfDay;
            var      timeBD     = ngay.Add(timespanBD);
            var      timeKT     = ngay.Add(timeSpanKT);

            if (timespanBD > timeSpanKT)
            {
                timeKT = timeKT.AddDays(1d);
            }

            cCa ca = tbCa.Tag as cCa;

            if (ca == null)
            {
                goto point;
            }

/*
 *                      if (ca.ID < 0 )
 *                      {
 *                              ca.Duty = new TS {Onn = timespanBD, Off = timeSpanKT};
 *                              XL.TaoCaTuDo(ca, timeBD, XL2._08gio, XL2.ChoPhepTre, XL2.ChoPhepSom, XL2.LamThemAfterOT, 1f, "8", false);//fix lỗi
 *                      }
 */
            if (ca.ID < int.MinValue + 100)
            {
                //ca.Duty = new TS {Onn = timespanBD, Off = timeSpanKT};
                //XL.TaoCaTuDo(ca, timeBD, XL2._08gio, XL2.ChoPhepTre, XL2.ChoPhepSom, XL2.LamThemAfterOT, 1f, "8", false);//fix lỗi
                XL.TaoCaTuDo(ca, timeBD);
            }
            else if (timeBD > ngay.Add(ca.Duty.Off) || timeKT < ngay.Add(ca.Duty.Onn))
            {
                goto point;
            }
            //var sophutOT = (checkXNLamThem.Checked && numSoPhutOT.Value > 0) ? (int)numSoPhutOT.Value : 0;
            TimeSpan OTCa = TimeSpan.Zero;            //ver 4.0.0.4

            if (checkXNLamThem.Checked)
            {
                TimeSpan.TryParseExact(maskPhutTinhLamThem.Text, @"hh\:mm", CultureInfo.InvariantCulture, out OTCa);
            }
            var sophutOT = Convert.ToInt32(OTCa.TotalMinutes);            //ver 4.0.0.4

            var tinhPCTC = (checkTinhPC150.Checked);

            tongGiothuc = timeKT - timeBD;
            TimeSpan TGGioLamViecTrongCa;

            XL.Vao(timeBD, ngay.Add(ca.Duty.Onn), ngay.Add(ca.chophepTreTS), true, true, out td_batdau_lv, out tre, out treKoTruVR);            //todo 4.0.0.8
            XL.Raa(timeKT, ngay.Add(ca.Duty.Off), ngay.Add(ca.chophepSomTS), false, false, out td_ketthuc_lv_chuaOT, out som, out somKoTruVR);  //todo 4.0.0.8
            XL.LamThem(td_ketthuc_lv_chuaOT, new TimeSpan(0, sophutOT, 0), out td_ketthuc_lv_daCoOT);
            if (timeKT < td_ketthuc_lv_daCoOT)
            {
                timeKT         = ngay.Add(ca.Duty.Off).Add(new TimeSpan(0, sophutOT, 0));
                dtpKTLam.Value = timeKT;
            }
            XL.Tinh_TGLamViecTrongCa(td_batdau_lv, td_ketthuc_lv_chuaOT, ca.LunchMin, out TGGioLamViecTrongCa);
            TGGioLamViec = TGGioLamViecTrongCa + OTCa;                //ver 4.0.0.4
            XL.Tinh_TGLamViec_Ca3(td_batdau_lv, td_ketthuc_lv_daCoOT, ngay.Add(XL2._22h00), ngay.AddDays(1d).Add(XL2._06h00), out TD_BD_LV_Ca3, out TD_KT_LV_Ca3, out TGLamBanDem, out QuaDem);
            TimeSpan TGLamThem     = XL.Tinh_TGLamThem(TGGioLamViec); //(TGGioLamViec - XL2._08gio) >= XL2._01phut ? (TGGioLamViec - XL2._08gio) : TimeSpan.Zero;
            float    cong_trong_ca = Convert.ToSingle(Math.Round(((TGGioLamViecTrongCa.TotalHours / ca.WorkingTimeTS.TotalHours) * ca.Workingday), 2));
            float    cong_ngoai_ca = Convert.ToSingle(Math.Round((OTCa.TotalHours / 8f), 2));

            Cong = cong_trong_ca + cong_ngoai_ca;

            XL.Tinh_PCTC(tinhPCTC, QuaDem, TGLamBanDem, TGLamThem, out tgTinhPC30, out tgTinhPC50, out tgTinhPCTCC3, out PhuCap30, out PhuCapTC, out PhuCapTCC3, out TongPhuCap);

point:
            tbTongGio.Text = tongGiothuc.ToString(@"hh\gmm\p");
            tbGioLam.Text  = TGGioLamViec.ToString(@"hh\gmm\p");
            tbCong.Text    = (Math.Round(Cong, 2)).ToString();
            tbPC.Text      = (TongPhuCap.ToString("0.0#"));
        }