private void buttonDelete_Click(object sender, EventArgs e)
        {
            int[] ids = this.GetSelectedIDs();
            if (ids.Length == 0)
            {
                MessageBox.Show("请选择要删除的项目", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (MessageBox.Show("确定删除选中的项目吗?\n重要提示:\n删除后所有零件的计划装车数量将会退回翻包作业单,无视实际装车数量!\n请谨慎操作!", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
            {
                return;
            }

            WMSEntities wmsEntities = new WMSEntities();

            try
            {
                //删除每个选中的出库单
                foreach (int id in ids)
                {
                    PutOutStorageTicket putOutStorageTicket = (from p in wmsEntities.PutOutStorageTicket
                                                               where p.ID == id
                                                               select p).FirstOrDefault();
                    if (putOutStorageTicket == null)
                    {
                        continue;
                    }
                    if (putOutStorageTicket.State != PutOutStorageTicketViewMetaData.STRING_STATE_NOT_LOADED)
                    {
                        MessageBox.Show("删除失败,只能删除未装车的出库单!\n如果需要强行删除,请使用修改功能将出库单的状态改为未装车", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                    //把没完成出库的条目在作业单的已分配出库数量里减去
                    var items = putOutStorageTicket.PutOutStorageTicketItem;
                    foreach (var item in items)
                    {
                        JobTicketItem jobTicketItem = (from j in wmsEntities.JobTicketItem
                                                       where j.ID == item.JobTicketItemID
                                                       select j).FirstOrDefault();
                        if (jobTicketItem == null)
                        {
                            continue;
                        }
                        jobTicketItem.ScheduledPutOutAmount -= ((item.ScheduledAmount ?? 0) * (item.UnitAmount ?? 1)) / (jobTicketItem.UnitAmount ?? 1);
                    }
                    wmsEntities.PutOutStorageTicket.Remove(putOutStorageTicket);
                }
                wmsEntities.SaveChanges();
            }
            catch
            {
                MessageBox.Show("删除失败,请检查网络连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            this.Invoke(new Action(() =>
            {
                this.Search(true);
            }));
            MessageBox.Show("删除成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        private void buttonModify_Click(object sender, EventArgs e)
        {
            int[] ids = Utilities.GetSelectedIDs(this.reoGridControlMain);
            if (ids.Length != 1)
            {
                MessageBox.Show("请选择一项进行修改", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            int id = ids[0];

            WMSEntities             wmsEntities             = new WMSEntities();
            PutOutStorageTicketItem putOutStorageTicketItem = null;
            StockInfo stockInfo = null;

            try
            {
                putOutStorageTicketItem = (from p in wmsEntities.PutOutStorageTicketItem where p.ID == id select p).FirstOrDefault();
                if (putOutStorageTicketItem == null)
                {
                    MessageBox.Show("出库单条目不存在,请重新查询", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                stockInfo = (from s in wmsEntities.StockInfo where s.ID == putOutStorageTicketItem.StockInfoID select s).FirstOrDefault();
            }
            catch
            {
                MessageBox.Show("修改失败,请检查网络连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            decimal oriScheduledAmountNoUnit     = (putOutStorageTicketItem.ScheduledAmount ?? 0) * (putOutStorageTicketItem.UnitAmount ?? 1);
            decimal oriRealAmountNoUnit          = (putOutStorageTicketItem.RealAmount ?? 0) * (putOutStorageTicketItem.UnitAmount ?? 1);
            decimal oriReturnQualityAmountNoUnit = putOutStorageTicketItem.ReturnQualityAmount * (putOutStorageTicketItem.ReturnQualityUnitAmount ?? 1);
            decimal oriReturnRejectAmountNoUnit  = putOutStorageTicketItem.ReturnRejectAmount * (putOutStorageTicketItem.ReturnRejectUnitAmount ?? 1);
            string  oriState = putOutStorageTicketItem.State;

            if (Utilities.CopyTextBoxTextsToProperties(this, putOutStorageTicketItem, PutOutStorageTicketItemViewMetaData.KeyNames, out string errorMessage) == false)
            {
                MessageBox.Show(errorMessage, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (Utilities.CopyComboBoxsToProperties(this, putOutStorageTicketItem, PutOutStorageTicketItemViewMetaData.KeyNames) == false)
            {
                MessageBox.Show("内部错误:读取复选框数据失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (putOutStorageTicketItem.RealAmount < 0 || putOutStorageTicketItem.RealAmount > putOutStorageTicketItem.ScheduledAmount)
            {
                MessageBox.Show("实际装车数量必须大于等于0并且小于计划装车数量", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            decimal deltaRealAmountNoUnit = ((putOutStorageTicketItem.RealAmount ?? 0) * (putOutStorageTicketItem.UnitAmount ?? 1)) - oriRealAmountNoUnit;
            decimal?returnQualityAmount   = putOutStorageTicketItem.ReturnQualityAmount * putOutStorageTicketItem.ReturnQualityUnitAmount;
            decimal?returnRejectAmount    = putOutStorageTicketItem.ReturnRejectAmount * putOutStorageTicketItem.ReturnRejectUnitAmount;
            decimal?deliverAmount         = putOutStorageTicketItem.RealAmount * putOutStorageTicketItem.UnitAmount;

            if (returnQualityAmount + returnRejectAmount > deliverAmount)
            {
                MessageBox.Show("正品返回数量与不良品返回数量之和不能超过实际发货数量!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            //如果修改了计划翻包数量,这个数量不可以大于发货单剩余可分配翻包数量
            //新的计划装车数量
            decimal newScheduledAmountNoUnit = (putOutStorageTicketItem.ScheduledAmount ?? 0) * (putOutStorageTicketItem.UnitAmount ?? 1);
            //变化的计划装车数量
            decimal deltaScheduledAmountNoUnit = newScheduledAmountNoUnit - oriScheduledAmountNoUnit;

            if (deltaScheduledAmountNoUnit != 0)
            {
                if (putOutStorageTicketItem.ScheduledAmount < putOutStorageTicketItem.RealAmount)
                {
                    MessageBox.Show("计划装车数量不可以小于实际装车数量!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                JobTicketItem jobTicketItem = (from j in wmsEntities.JobTicketItem
                                               where j.ID == putOutStorageTicketItem.JobTicketItemID
                                               select j).FirstOrDefault();
                if (jobTicketItem != null)
                {
                    //实际翻包总数量
                    decimal jobTicketItemRealAmount = (jobTicketItem.RealAmount ?? 0) * (jobTicketItem.UnitAmount ?? 1);
                    //剩余可分配装车数量
                    decimal restScheduableAmountNoUnit = jobTicketItemRealAmount - (jobTicketItem.ScheduledPutOutAmount ?? 0) * (jobTicketItem.UnitAmount ?? 1);
                    if (restScheduableAmountNoUnit < deltaScheduledAmountNoUnit)
                    {
                        MessageBox.Show(string.Format("翻包作业单剩余可分配装车数量不足!\n剩余可分配装车数:{0}({1})", Utilities.DecimalToString(restScheduableAmountNoUnit / (putOutStorageTicketItem.UnitAmount ?? 1)), putOutStorageTicketItem.Unit), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                    //把多的计划装车数量加进作业单的已分配装车数里
                    jobTicketItem.ScheduledPutOutAmount += deltaScheduledAmountNoUnit / jobTicketItem.UnitAmount;
                }
            }
            int jobPersonID     = this.jobPersonGetter();
            int confirmPersonID = this.confirmPersonGetter();

            putOutStorageTicketItem.JobPersonID     = jobPersonID == -1 ? null : (int?)jobPersonID;
            putOutStorageTicketItem.ConfirmPersonID = confirmPersonID == -1 ? null : (int?)confirmPersonID;
            if (putOutStorageTicketItem.RealAmount == putOutStorageTicketItem.ScheduledAmount)
            {
                putOutStorageTicketItem.State = PutOutStorageTicketItemViewMetaData.STRING_STATE_ALL_LOADED;
            }
            else if (putOutStorageTicketItem.RealAmount == 0)
            {
                putOutStorageTicketItem.State = PutOutStorageTicketItemViewMetaData.STRING_STATE_WAIT_FOR_LOAD;
            }
            else
            {
                putOutStorageTicketItem.State = PutOutStorageTicketItemViewMetaData.STRING_STATE_PART_LOADED;
            }

            if (stockInfo != null)
            {
                //更新发货区,已分配发货数量
                stockInfo.ShipmentAreaAmount      -= deltaRealAmountNoUnit;
                stockInfo.ScheduledShipmentAmount -= deltaRealAmountNoUnit;
                //更新退回数量
                decimal deltaReturnQualityAmountNoUnit = putOutStorageTicketItem.ReturnQualityAmount * (putOutStorageTicketItem.ReturnQualityUnitAmount ?? 1) - oriReturnQualityAmountNoUnit;
                decimal deltaReturnRejectAmountNoUnit  = putOutStorageTicketItem.ReturnRejectAmount * (putOutStorageTicketItem.ReturnRejectUnitAmount ?? 1) - oriReturnRejectAmountNoUnit;
                stockInfo.ShipmentAreaAmount += deltaReturnQualityAmountNoUnit;
                stockInfo.RejectAreaAmount   += deltaReturnRejectAmountNoUnit;
            }

            try
            {
                wmsEntities.SaveChanges();
                this.UpdatePutOutStorageTicketStateSync();
            }
            catch
            {
                MessageBox.Show("修改失败,请检查网络连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            this.Invoke(new Action(() =>
            {
                this.Search(putOutStorageTicketItem.ID);
            }));
            MessageBox.Show("修改成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        /// <summary>
        /// 无脑生成作业单,不选零件不填数量。
        /// </summary>
        /// <param name="shipmentTicketIDs"></param>
        /// <param name="wmsEntities"></param>
        public static bool GenerateJobTicketFullSync(int shipmentTicketID, WMSEntities wmsEntities, DateTime?createTime = null)
        {
            ShipmentTicket shipmentTicket = (from s in wmsEntities.ShipmentTicket
                                             where s.ID == shipmentTicketID
                                             select s).FirstOrDefault();

            if (shipmentTicket == null)
            {
                MessageBox.Show("发货单不存在,请重新查询", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }
            ShipmentTicketItem[] shipmentTicketItems = (from s in wmsEntities.ShipmentTicketItem
                                                        where s.ShipmentTicketID == shipmentTicketID
                                                        select s).ToArray();
            List <JobTicketItem> newJobTicketItems = new List <JobTicketItem>();

            for (int i = 0; i < shipmentTicketItems.Length; i++)
            {
                ShipmentTicketItem shipmentTicketItem = shipmentTicketItems[i];
                if (shipmentTicketItem == null)
                {
                    MessageBox.Show("发货单条目不存在,可能已被删除,请重新查询", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(false);
                }
                decimal restScheduableAmount = (shipmentTicketItem.ShipmentAmount - (shipmentTicketItem.ScheduledJobAmount ?? 0)) ?? 0;
                if (restScheduableAmount <= 0)
                {
                    continue;
                }
                var jobTicketItem = new JobTicketItem();
                jobTicketItem.ScheduledAmount      = restScheduableAmount;
                jobTicketItem.StockInfoID          = shipmentTicketItem.StockInfoID;
                jobTicketItem.ShipmentTicketItemID = shipmentTicketItem.ID;
                jobTicketItem.State      = JobTicketItemViewMetaData.STRING_STATE_UNFINISHED;
                jobTicketItem.Unit       = shipmentTicketItem.Unit;
                jobTicketItem.UnitAmount = shipmentTicketItem.UnitAmount;
                jobTicketItem.RealAmount = 0;
                shipmentTicketItem.ScheduledJobAmount = (shipmentTicketItem.ScheduledJobAmount ?? 0) + jobTicketItem.ScheduledAmount;
                newJobTicketItems.Add(jobTicketItem);
            }
            if (newJobTicketItems.Count == 0)
            {
                MessageBox.Show("发货单 " + shipmentTicket.No + " 中无可分配翻包的零件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return(false);
            }

            JobTicket newJobTicket = new JobTicket();

            foreach (JobTicketItem item in newJobTicketItems)
            {
                newJobTicket.JobTicketItem.Add(item);
            }
            wmsEntities.JobTicket.Add(newJobTicket);

            newJobTicket.State            = JobTicketViewMetaData.STRING_STATE_UNFINISHED;
            newJobTicket.ShipmentTicketID = shipmentTicket.ID;
            newJobTicket.ProjectID        = GlobalData.ProjectID;
            newJobTicket.WarehouseID      = GlobalData.WarehouseID;
            newJobTicket.CreateUserID     = GlobalData.UserID;
            newJobTicket.CreateTime       = createTime ?? DateTime.Now;

            if (string.IsNullOrWhiteSpace(newJobTicket.JobTicketNo))
            {
                DateTime createDay      = new DateTime(shipmentTicket.CreateTime.Value.Year, shipmentTicket.CreateTime.Value.Month, shipmentTicket.CreateTime.Value.Day);
                DateTime nextDay        = createDay.AddDays(1);
                int      maxRankOfToday = Utilities.GetMaxTicketRankOfDay((from j in wmsEntities.JobTicket
                                                                           where j.CreateTime >= createDay && j.CreateTime < nextDay
                                                                           select j.JobTicketNo).ToArray());
                newJobTicket.JobTicketNo = Utilities.GenerateTicketNo("Z", newJobTicket.CreateTime.Value, maxRankOfToday + 1);
            }
            wmsEntities.SaveChanges();
            //更新发货单状态
            ShipmentTicketUtilities.UpdateShipmentTicketStateSync(shipmentTicketID, wmsEntities, true);
            return(true);
        }
        private void buttonModify_Click(object sender, EventArgs e)
        {
            int[] ids = Utilities.GetSelectedIDs(this.reoGridControlMain);
            if (ids.Length != 1)
            {
                MessageBox.Show("请选择一项进行修改", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            int id = ids[0];

            WMSEntities   wmsEntities1  = new WMSEntities();
            JobTicketItem jobTicketItem = null;

            try
            {
                jobTicketItem = (from j in wmsEntities1.JobTicketItem where j.ID == id select j).FirstOrDefault();
            }
            catch
            {
                MessageBox.Show("修改失败,请检查网络连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (jobTicketItem == null)
            {
                MessageBox.Show("作业任务不存在,请重新查询", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            this.Invoke(new Action(() =>
            {
                decimal oriScheduledAmountNoUnit = (jobTicketItem.ScheduledAmount ?? 0) * (jobTicketItem.UnitAmount ?? 1); //原翻包数量*单位
                if (Utilities.CopyTextBoxTextsToProperties(this, jobTicketItem, JobTicketItemViewMetaData.KeyNames, out string errorMessage) == false)
                {
                    MessageBox.Show(errorMessage, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (Utilities.CopyComboBoxsToProperties(this, jobTicketItem, JobTicketItemViewMetaData.KeyNames) == false)
                {
                    MessageBox.Show("内部错误:拷贝单选框数据失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (jobTicketItem.RealAmount > jobTicketItem.ScheduledAmount)
                {
                    MessageBox.Show("实际翻包数量不能超过计划翻包数量!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (jobTicketItem.RealAmount < jobTicketItem.ScheduledPutOutAmount)
                {
                    MessageBox.Show("实际翻包数量不能小于已分配出库数量!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                //如果修改了计划翻包数量,这个数量不可以大于发货单剩余可分配翻包数量
                //新的计划翻包数量
                decimal newScheduledAmountNoUnit = (jobTicketItem.ScheduledAmount ?? 0) * (jobTicketItem.UnitAmount ?? 1);
                //变化的计划翻包数量
                decimal deltaScheduledAmountNoUnit = newScheduledAmountNoUnit - oriScheduledAmountNoUnit;
                if (deltaScheduledAmountNoUnit != 0)
                {
                    if (jobTicketItem.ScheduledAmount < jobTicketItem.RealAmount)
                    {
                        MessageBox.Show("计划翻包数量不可以小于实际翻包数量!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                    ShipmentTicketItem shipmentTicketItem = (from s in wmsEntities1.ShipmentTicketItem
                                                             where s.ID == jobTicketItem.ShipmentTicketItemID
                                                             select s).FirstOrDefault();
                    if (shipmentTicketItem != null)
                    {
                        //发货总数量
                        decimal shipmentAmountNoUnit = (shipmentTicketItem.ShipmentAmount ?? 0) * (shipmentTicketItem.UnitAmount ?? 1);
                        //剩余可分配翻包数量
                        decimal restScheduableAmountNoUnit = shipmentAmountNoUnit - (shipmentTicketItem.ScheduledJobAmount ?? 0) * (shipmentTicketItem.UnitAmount ?? 1);
                        if (restScheduableAmountNoUnit < deltaScheduledAmountNoUnit)
                        {
                            MessageBox.Show(string.Format("发货单剩余可分配翻包数量不足!\n剩余可分配翻包数:{0}({1})", Utilities.DecimalToString(restScheduableAmountNoUnit / (jobTicketItem.UnitAmount ?? 1)), jobTicketItem.Unit), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        //把多的计划翻包数量加进发货单的已分配发货数里
                        shipmentTicketItem.ScheduledJobAmount += deltaScheduledAmountNoUnit / shipmentTicketItem.UnitAmount;
                    }
                }

                int jobPersonID               = this.JobPersonIDGetter();
                int confirmPersonID           = this.ConfirmPersonIDGetter();
                jobTicketItem.JobPersonID     = jobPersonID == -1 ? null : (int?)jobPersonID;
                jobTicketItem.ConfirmPersonID = confirmPersonID == -1 ? null : (int?)confirmPersonID;
                if (jobTicketItem.RealAmount == jobTicketItem.ScheduledAmount)
                {
                    jobTicketItem.State = JobTicketItemViewMetaData.STRING_STATE_ALL_FINISHED;
                }
                else if (jobTicketItem.RealAmount == 0)
                {
                    jobTicketItem.State = JobTicketItemViewMetaData.STRING_STATE_UNFINISHED;
                }
                else
                {
                    jobTicketItem.State = JobTicketItemViewMetaData.STRING_STATE_PART_FINISHED;
                }

                try
                {
                    wmsEntities1.SaveChanges();
                }
                catch
                {
                    MessageBox.Show("修改失败,请检查网络连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                this.UpdateJobTicketStateSync();
                this.Invoke(new Action(() => this.Search()));
                MessageBox.Show("修改成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }));
        }