public ActionResult EditSave(MaintenanceRecord data)
        {
            recsys_maintenance maintenance;
            recsys_relate_customers customerData;

            //# validation
            if (data.id < 0)
                throw new SystemException("Invalid Entity ID");

            //# get old record
            var records = from m in this._db.recsys_maintenance
                          join c in this._db.recsys_relate_customers on m.customer_id equals c.id into cs
                          from c in cs.DefaultIfEmpty()
                          where m.id == data.id
                          select new
                          {
                              Maintenance = m,
                              CustomerData = c
                          };
            var record = records.FirstOrDefault();

            Member member = new Member("users");

            //# validation
            if (record == null)
                throw new RecordNotFoundException();

            maintenance = record.Maintenance;
            customerData = record.CustomerData;

            //# validation
            if (maintenance == null || customerData == null)
                throw new RecordNotFoundException();
            if (!maintenance.last_update.HasValue)
                throw new ImproperDataException();
            if (maintenance.last_update.Value > data.FetchRecordTime)
                throw new OptimisticConcurrencyException("資料已被其他使用者更新");

            if (string.IsNullOrEmpty(data.start_date))
            {
                data.SaveResult.WarningMessage = "請填上開始日期";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }
            if (string.IsNullOrEmpty(data.end_date))
            {
                data.SaveResult.WarningMessage = "請填上完結日期";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }

            if (DateTime.ParseExact(data.end_date, "dd-MM-yyyy", null) < DateTime.ParseExact(data.start_date, "dd-MM-yyyy", null))
            {
                data.SaveResult.WarningMessage = "完結日期應在開始日期之後";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }

            if (!data.routine_id.HasValue)
            {
                data.SaveResult.WarningMessage = "請選擇Routine";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }
            if (!String.IsNullOrEmpty(data.chq_no))
            {
                if (data.chq_no.Length > 50)
                {
                    data.SaveResult.WarningMessage = "請修改Cheque No.至50字以內";
                    data.SaveResult.SavedSuccessfully = false;
                    return Json(data);
                }
            }

            bool createNewDistrict = false;
            if (!string.IsNullOrEmpty(data.WorkingDistrictName))
            {
                recsys_district workingDistrict = this._db.recsys_district.Where(x => x.name.Trim().ToUpper().Equals(data.WorkingDistrictName.Trim().ToUpper())).SingleOrDefault();
                if (workingDistrict != null)
                {
                    data.district2 = workingDistrict.id;
                    data.group_id = workingDistrict.group_id;
                }
                else
                    createNewDistrict = true;
            }

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = data.WorkingDistrictName.Trim(),
                    name = data.WorkingDistrictName.Trim(),
                    group_id = this._db.recsys_group.Where(x => x.name.Equals("Unknown Group For System Migration")).SingleOrDefault().id,
                    region = 4,
                    status = 1,
                    last_update = DateTime.Now,
                    update_user_id = (int)member.infoBySession("id")
                };

                this._db.recsys_district.AddObject(addNewDistrict);
                this._db.SaveChanges();

                data.district2 = this._db.recsys_district.Where(x => x.name.Equals(data.WorkingDistrictName.Trim())).SingleOrDefault().id;
                data.group_id = this._db.recsys_district.Where(x => x.name.Equals(data.WorkingDistrictName.Trim())).SingleOrDefault().group_id;
            }

            createNewDistrict = false;
            if (!string.IsNullOrEmpty(data.MailingDistrictName))
            {
                recsys_district mailingDistrict = this._db.recsys_district.Where(x => x.name.Trim().ToUpper().Equals(data.MailingDistrictName.Trim().ToUpper())).SingleOrDefault();
                if (mailingDistrict != null)
                {
                    data.district1 = mailingDistrict.id;
                    data.group_id = mailingDistrict.group_id;
                }
                else
                    createNewDistrict = true;
            }

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = data.MailingDistrictName.Trim(),
                    name = data.MailingDistrictName.Trim(),
                    group_id = this._db.recsys_group.Where(x => x.name.Equals("Unknown Group For System Migration")).SingleOrDefault().id,
                    region = 4,
                    status = 1,
                    last_update = DateTime.Now,
                    update_user_id = (int)member.infoBySession("id")
                };

                this._db.recsys_district.AddObject(addNewDistrict);
                this._db.SaveChanges();

                data.district1 = this._db.recsys_district.Where(x => x.name.Equals(data.MailingDistrictName.Trim())).SingleOrDefault().id;
                data.group_id = this._db.recsys_district.Where(x => x.name.Equals(data.MailingDistrictName.Trim())).SingleOrDefault().group_id;
            }

            //# saving
            //# mapping
            maintenance.amount = data.amount;
            maintenance.chq_no = data.chq_no;
            maintenance.chq_receive_date = DateChecking(data.chq_receive_date);
            maintenance.billing_date = DateChecking(data.billing_date);
            maintenance.checking_date = DateChecking(data.checking_date);
            maintenance.confirm_date = DateChecking(data.confirm_date);
            maintenance.end_date = DateChecking(data.end_date);
            maintenance.invoice = data.invoice;
            maintenance.invoice_date = DateChecking(data.invoice_date);
            maintenance.issue_date = DateChecking(data.issue_date);
            maintenance.last_update = DateTime.Now;
            maintenance.model = data.model;
            maintenance.payment = data.payment;
            maintenance.period = record.Maintenance.period;
            maintenance.printed = (byte)( data.printed ? 1 : 0);
            maintenance.first_print_Date = data.first_print_date;
            maintenance.schedule = data.schedule;
            maintenance.routine = data.routine;
            maintenance.routine2 = data.routine2;
            //# alter maintenance remark
            if (!string.IsNullOrEmpty(data.remark2))
            {
                int index1 = data.remark2.IndexOf("[");
                int index2 = data.remark2.IndexOf("]");
                if (index1 > -1 && index2 > -1)
                    data.remark2 = data.remark2.Substring(index2 + 1);
            }
            recsys_routine routine = null;
            if (data.routine_id != null)
            {
                routine = (from r in this._db.recsys_routine
                           where r.id == data.routine_id
                           select r).FirstOrDefault();
            }
            maintenance.remark = routine != null ? "[" + routine.description_chi + "]" + data.remark2 : data.remark2;
            maintenance.lang = data.lang;
            maintenance.start_date = DateChecking(data.start_date);
            maintenance.status = (byte) data.status;
            maintenance.update_user_id = (int)member.infoBySession("id");
            maintenance.master_routine_id = data.routine_id;
            customerData.address1 = data.address1;
            customerData.address2 = data.address2;
            customerData.contact = data.contact;
            customerData.district1 = data.district1;
            customerData.district2 = data.district2;
            customerData.email = data.email;
            customerData.fax1 = data.fax1;
            customerData.fax2 = data.fax2;
            customerData.group_id = data.group_id;
            customerData.name = data.name;
            customerData.chi_name = data.chi_name;
            customerData.remark = data.remark;
            customerData.tel1 = data.tel1;
            customerData.tel2 = data.tel2;
            customerData.title = (byte)data.title;

            try
            {
                this._db.SaveChanges();
                this._db.Refresh(System.Data.Objects.RefreshMode.StoreWins, maintenance);
                this._db.Refresh(System.Data.Objects.RefreshMode.StoreWins, customerData);

                bool generateOrderYet = data.auto_gen_order.HasValue ? data.auto_gen_order.Value : false;
                if (!generateOrderYet && !string.IsNullOrEmpty(data.confirm_date))
                {
                    IEnumerable<recsys_order> orders;

                    //# logic: create orders (定期保養)
                    if (this.TryGenerateOrdersForMaintenance(maintenance, this._db.recsys_routine.FirstOrDefault(theRoutine => theRoutine.id == maintenance.master_routine_id), out orders))
                    {
                        maintenance.period = orders.Count();
                        maintenance.auto_gen_order = true;

                        this._db.SaveChanges();
                        data.SaveResult.SavedSuccessfully = true;
                    }
                }

                data.id = maintenance.id;
                data.center = customerData.center;
                data.SaveResult.SavedSuccessfully = true;
            }
            catch (OptimisticConcurrencyException)
            {
                //# log down
            }

            return Json(data);
        }
        public ActionResult Edit(int id)
        {
            MaintenanceRecord model;

            //# validation
            if (id < 0)
                throw new SystemException("Invalid Entity ID");

            //# get old record
            var records = from m in this._db.recsys_maintenance
                          join cd in this._db.recsys_relate_customers on m.customer_id equals cd.id into cds
                          from cd in cds.DefaultIfEmpty()
                          join c in this._db.recsys_customers on cd.customer_id equals c.id into cs
                          from c in cs.DefaultIfEmpty()
                          join u in this._db.recsys_users on m.update_user_id equals u.id into uss
                          from u in uss.DefaultIfEmpty()
                          join d1 in this._db.recsys_district on cd.district1 equals d1.id into d1s
                          from d1 in d1s.DefaultIfEmpty()
                          join d2 in this._db.recsys_district on cd.district2 equals d2.id into d2s
                          from d2 in d2s.DefaultIfEmpty()
                          where m.id == id
                          select
                          new
                          {
                              m,
                              cd,
                              masterCustomer = c,
                              UpdateUserName = u.name,
                              WorkingDistrictName = d2.name,
                              MailingDistrictName = d1.name
                          };

            var record = records.FirstOrDefault();

            //# validation
            if (record == null)
                throw new RecordNotFoundException();

            model = new MaintenanceRecord()
            {
                //# field mapping
                auto_gen_order = record.m.auto_gen_order,
                address1 = record.cd.address1,
                address2 = record.cd.address2,
                amount = record.m.amount,
                chq_no = record.m.chq_no,
                chq_receive_date = record.m.chq_receive_date.HasValue ? record.m.chq_receive_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                billing_date = record.m.billing_date.HasValue ? record.m.billing_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                center = record.cd.center,
                checking_date = record.m.checking_date.HasValue ? record.m.checking_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                code = record.cd.code,
                confirm_date = record.m.confirm_date.HasValue ? record.m.confirm_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                contact = record.cd.contact,
                create_date = record.m.create_date,
                customer_code = record.cd.customer_code,
                district1 = record.cd.district1,
                district2 = record.cd.district2,
                email = record.cd.email,
                end_date = record.m.end_date.HasValue ? record.m.end_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                enquery_id = record.m.enquery_id,
                fax1 = record.cd.fax1,
                fax2 = record.cd.fax2,
                group_id = record.cd.group_id,
                id = record.m.id,
                invoice = record.m.invoice,
                invoice_date = record.m.invoice_date.HasValue ? record.m.invoice_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                issue_date = record.m.issue_date.HasValue ? record.m.issue_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                last_update = record.m.last_update,
                last_update_user_name = record.UpdateUserName,
                MailingDistrictName = record.MailingDistrictName,
                model = record.m.model,
                name = record.cd.name,
                payment = record.m.payment,
                period = record.m.period,
                prefix = record.cd.prefix,
                printed = record.m.printed == 1,
                first_print_date = record.m.first_print_Date,
                remark = record.cd.remark,
                remark2 = record.m.remark,
                schedule = record.m.schedule,
                start_date = record.m.start_date.HasValue ? record.m.start_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                routine = record.m.routine,
                routine2 = record.m.routine2,
                routine_id = record.m.master_routine_id,
                lang = record.m.lang ?? 1,
                status = record.m.status,
                tel1 = record.cd.tel1,
                tel2 = record.cd.tel2,
                title = record.cd.title.HasValue ? record.cd.title.Value : 0,
                type = record.cd.type.HasValue ? record.cd.type.Value : 0,
                WorkingDistrictName = record.WorkingDistrictName,
                //customer_reference_number = record.cd.reference_number,
                //get the newset number
                customer_reference_number = record.masterCustomer.reference_number,
                chi_name = record.cd.chi_name,

                //# settings
                SaveResult = null,
                IsClone = false,
                Mode = PageMode.Edit,
                FetchRecordTime = DateTime.Now,
                RelateTableName = "Maintenance",

                //# masters
                Districts = this._db.recsys_district
                                                        .Where(theDistrict => theDistrict.status == 1)
                                                        .OrderBy(theDistrict => theDistrict.name),
                Groups = this._db.recsys_group
                                                        .Where(theGroup => theGroup.status == 1)
                                                        .OrderBy(theGroup => theGroup.name),
                Routines = this._db.recsys_routine
                                                        .Where(theRoutine => theRoutine.status == 1),
                Languages = this._lang,
                Titles = this._title,
                Statuses = this._status
            };

            return PartialView("AddEdit", model);
        }
        public ActionResult Clone(int cloneFrom_ID,int masterCustomerID)
        {
            MaintenanceRecord model;
            recsys_maintenance cloneFrom;

            //# validation
            if (masterCustomerID < 0)
                throw new SystemException("Invalid Entity ID");

            //# get old master customer record
            var records = from c in this._db.recsys_customers
                          join d1 in this._db.recsys_district on c.district1 equals d1.id into d1s
                          from d1 in d1s.DefaultIfEmpty()
                          join d2 in this._db.recsys_district on c.district2 equals d2.id into d2s
                          from d2 in d2s.DefaultIfEmpty()
                          where c.id == masterCustomerID
                          select new
                          {
                              masterCustomer = c,
                              MailingDistrictName = d1.name,
                              WorkingDistrictName = d2.name
                          };
            var record = records.FirstOrDefault();

            //# get clone from maintenance
            cloneFrom = this._db.recsys_maintenance.Where(theMaintenance => theMaintenance.id == cloneFrom_ID).FirstOrDefault();

            //# validation
            if (record == null)
                throw new RecordNotFoundException();
            if (cloneFrom == null)
                throw new RecordNotFoundException();

            model = new MaintenanceRecord()
            {
                //# customer data fields mapping
                address1 = record.masterCustomer.address1,
                address2 = record.masterCustomer.address2,
                center = record.masterCustomer.center,
                code = record.masterCustomer.code,
                contact = record.masterCustomer.contact,
                customer_code = record.masterCustomer.customer_code,
                district1 = record.masterCustomer.district1,
                district2 = record.masterCustomer.district2,
                email = record.masterCustomer.email,
                fax1 = record.masterCustomer.fax1,
                fax2 = record.masterCustomer.fax2,
                MailingDistrictName = record.MailingDistrictName,
                MasterCustomerID = masterCustomerID,
                name = record.masterCustomer.name,
                prefix = record.masterCustomer.prefix,
                remark = record.masterCustomer.remark,
                tel1 = record.masterCustomer.tel1,
                tel2 = record.masterCustomer.tel2,
                title = record.masterCustomer.title,
                type = record.masterCustomer.type,
                WorkingDistrictName = record.WorkingDistrictName,
                chi_name = record.masterCustomer.chi_name,

                //# clone from maintenance mapping
                model = cloneFrom.model,
                amount = cloneFrom.amount,
                start_date = cloneFrom.start_date.HasValue ? cloneFrom.start_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                end_date = cloneFrom.end_date.HasValue ? cloneFrom.end_date.Value.ToString("dd-MM-yyyy") : string.Empty,
                period = cloneFrom.period,
                lang = (byte)((cloneFrom.lang != null && cloneFrom.lang != 0) ? cloneFrom.lang.Value : 1),

                //# default
                status = (int)RecordStatus.Active,
                create_date = DateTime.Now,

                //# settings
                IsClone = true,
                Mode = PageMode.Add,

                //# masters
                Districts = this._db.recsys_district
                                                        .Where(theDistrict => theDistrict.status == 1)
                                                        .OrderBy(theDistrict => theDistrict.name),
                Groups = this._db.recsys_group
                                                        .Where(theGroup => theGroup.status == 1)
                                                        .OrderBy(theGroup => theGroup.name),
                Routines = this._db.recsys_routine
                                                        .Where(theRoutine => theRoutine.status == 1),
                Languages = this._lang,
                Titles = this._title,
                Statuses = this._status

            };

            return PartialView("AddEdit", model);
        }
        public ActionResult Add(int masterCustomerID)
        {
            MaintenanceRecord model;

            //# validation
            if (masterCustomerID < 0)
                throw new SystemException("Invalid Entity ID");

            //# get old master customer record
            var records = from c in this._db.recsys_customers
                          join d1 in this._db.recsys_district on c.district1 equals d1.id into d1s
                          from d1 in d1s.DefaultIfEmpty()
                          join d2 in this._db.recsys_district on c.district2 equals d2.id into d2s
                          from d2 in d2s.DefaultIfEmpty()
                          where c.id == masterCustomerID
                          select new
                          {
                              masterCustomer = c,
                              MailingDistrictName = d1.name,
                              WorkingDistrictName = d2.name
                          };
            var record = records.FirstOrDefault();

            //# payment term
            string payment_term = "";
            string sql = "SELECT * FROM recsys_system_parameter s WHERE s.status = '1'";
            SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["reportConnection"].ConnectionString);
            using (connection)
            {
                SqlCommand command = new SqlCommand(sql, connection);
                connection.Open();
                SqlDataReader reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        if (reader["name"].ToString().Equals("maint_payment_term"))
                            payment_term = reader["value"].ToString();
                    }
                }

                reader.Close();
            }

            //# validation
            if (record == null)
                throw new RecordNotFoundException();

            model = new MaintenanceRecord()
            {
                //# customer data fields mapping
                address1 = record.masterCustomer.address1,
                address2 = record.masterCustomer.address2,
                center = record.masterCustomer.center,
                code = record.masterCustomer.code,
                contact = record.masterCustomer.contact,
                customer_code = record.masterCustomer.customer_code,
                district1 = record.masterCustomer.district1,
                district2 = record.masterCustomer.district2,
                email = record.masterCustomer.email,
                fax1 = record.masterCustomer.fax1,
                fax2 = record.masterCustomer.fax2,
                MailingDistrictName = record.MailingDistrictName,
                MasterCustomerID = masterCustomerID,
                name = record.masterCustomer.name,
                prefix = record.masterCustomer.prefix,
                customer_reference_number = record.masterCustomer.reference_number,
                remark = record.masterCustomer.remark,
                tel1 = record.masterCustomer.tel1,
                tel2 = record.masterCustomer.tel2,
                title = record.masterCustomer.title,
                type = record.masterCustomer.type,
                WorkingDistrictName = record.WorkingDistrictName,
                payment = payment_term,
                chi_name = record.masterCustomer.chi_name,

                //# default
                status = (int)RecordStatus.Active,
                create_date = DateTime.Now,

                //# settings
                IsClone = false,
                Mode = PageMode.Add,

                //# masters
                Districts = this._db.recsys_district
                                                        .Where(theDistrict => theDistrict.status == 1)
                                                        .OrderBy(theDistrict => theDistrict.name),
                Groups = this._db.recsys_group
                                                        .Where(theGroup => theGroup.status == 1)
                                                        .OrderBy(theGroup => theGroup.name),
                Routines = this._db.recsys_routine
                                                        .Where(theRoutine => theRoutine.status == 1),
                Languages = this._lang,
                Titles = this._title,
                Statuses = this._status,
                auto_gen_order = false
            };

            return PartialView("AddEdit", model);
        }
        public ActionResult AddSave(MaintenanceRecord data)
        {
            //# validation
            if (string.IsNullOrEmpty(data.start_date))
            {
                data.SaveResult.WarningMessage = "請填上開始日期";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }
            if (string.IsNullOrEmpty(data.end_date))
            {
                data.SaveResult.WarningMessage = "請填上完結日期";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }
            if (DateTime.ParseExact(data.end_date, "dd-MM-yyyy", null) < DateTime.ParseExact(data.start_date, "dd-MM-yyyy", null))
            {
                data.SaveResult.WarningMessage = "完結日期應在開始日期之後";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }

            if (!data.routine_id.HasValue)
            {
                data.SaveResult.WarningMessage = "請選擇Routine";
                data.SaveResult.SavedSuccessfully = false;
                return Json(data);
            }

            if (!String.IsNullOrEmpty(data.chq_no))
            {
                if (data.chq_no.Length > 50)
                {
                    data.SaveResult.WarningMessage = "請修改Cheque No.至50字以內";
                    data.SaveResult.SavedSuccessfully = false;
                    return Json(data);
                }
            }

            Member member;
            recsys_customers masterCustomer;
            recsys_relate_customers customerData;
            recsys_maintenance maintenance;

            //# validation
            if (data.MasterCustomerID < 0)
                throw new SystemException("Invalid Entity ID");

            //# get old master customer record
            masterCustomer = this._db.recsys_customers.FirstOrDefault(theCustomer => theCustomer.id == data.MasterCustomerID);

            //# validation
            if (masterCustomer == null)
                throw new RecordNotFoundException();

            member = new Member("users");

            bool createNewDistrict = false;
            if (!string.IsNullOrEmpty(data.WorkingDistrictName))
            {
                recsys_district workingDistrict = this._db.recsys_district.Where(x => x.name.Trim().ToUpper().Equals(data.WorkingDistrictName.Trim().ToUpper())).SingleOrDefault();
                if (workingDistrict != null)
                {
                    data.district2 = workingDistrict.id;
                    data.group_id = workingDistrict.group_id;
                }
                else
                    createNewDistrict = true;
            }

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = data.WorkingDistrictName.Trim(),
                    name = data.WorkingDistrictName.Trim(),
                    group_id = this._db.recsys_group.Where(x => x.name.Equals("Unknown Group For System Migration")).SingleOrDefault().id,
                    region = 4,
                    status = 1,
                    last_update = DateTime.Now,
                    update_user_id = (int)member.infoBySession("id")
                };

                this._db.recsys_district.AddObject(addNewDistrict);
                this._db.SaveChanges();

                data.district2 = this._db.recsys_district.Where(x => x.name.Equals(data.WorkingDistrictName.Trim())).SingleOrDefault().id;
                data.group_id = this._db.recsys_district.Where(x => x.name.Equals(data.WorkingDistrictName.Trim())).SingleOrDefault().group_id;
            }

            createNewDistrict = false;
            if (!string.IsNullOrEmpty(data.MailingDistrictName))
            {
                recsys_district mailingDistrict = this._db.recsys_district.Where(x => x.name.Trim().ToUpper().Equals(data.MailingDistrictName.Trim().ToUpper())).SingleOrDefault();
                if (mailingDistrict != null)
                {
                    data.district1 = mailingDistrict.id;
                    data.group_id = mailingDistrict.group_id;
                }
                else
                    createNewDistrict = true;
            }

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = data.MailingDistrictName.Trim(),
                    name = data.MailingDistrictName.Trim(),
                    group_id = this._db.recsys_group.Where(x => x.name.Equals("Unknown Group For System Migration")).SingleOrDefault().id,
                    region = 4,
                    status = 1,
                    last_update = DateTime.Now,
                    update_user_id = (int)member.infoBySession("id")
                };

                this._db.recsys_district.AddObject(addNewDistrict);
                this._db.SaveChanges();

                data.district1 = this._db.recsys_district.Where(x => x.name.Equals(data.MailingDistrictName.Trim())).SingleOrDefault().id;
                data.group_id = this._db.recsys_district.Where(x => x.name.Equals(data.MailingDistrictName.Trim())).SingleOrDefault().group_id;
            }

            //# mapping
            customerData = new recsys_relate_customers()
            {
                address1 = data.address1,
                address2 = data.address2,
                center = masterCustomer.center,
                code = masterCustomer.code,
                contact = data.contact,
                customer_code = masterCustomer.customer_code,
                customer_id = masterCustomer.id,
                district1 = data.district1,
                district2 = data.district2,
                email = data.email,
                fax1 = data.fax1,
                fax2 = data.fax2,
                group_id = data.group_id,
                manual_input_code = masterCustomer.manual_input_code,
                name = data.name,
                chi_name = data.chi_name,
                prefix = masterCustomer.prefix,
                relate_type = (int) Rec_System.Models.Customers.CustomerDataRelateType.Maintenance,
                reference_number = masterCustomer.reference_number,
                remark = data.remark,
                tel1 = data.tel1,
                tel2 = data.tel2,
                title = (byte) data.title,
                type = (byte) masterCustomer.type
            };

            this._db.recsys_relate_customers.AddObject(customerData);
            recsys_routine routine = null;
            if (data.routine_id != null)
            {
                routine = (from r in this._db.recsys_routine
                              where r.id == data.routine_id
                              select r).FirstOrDefault();
            }
            maintenance = new recsys_maintenance()
            {
                amount = data.amount,
                chq_no = data.chq_no,
                chq_receive_date = DateChecking(data.chq_receive_date),
                billing_date = DateChecking(data.billing_date),
                checking_date = DateChecking(data.checking_date),
                confirm_date = DateChecking(data.confirm_date),
                create_date = DateTime.Now,
                end_date = DateChecking(data.end_date),
                invoice = data.invoice,
                invoice_date = DateChecking(data.invoice_date),
                issue_date = DateChecking(data.issue_date),
                last_update = DateTime.Now,
                model = data.model,
                routine = data.routine,
                routine2 = data.routine2,
                lang = data.lang,
                payment = data.payment,
                period = data.period,
                printed = (byte)(data.printed ? 1 : 0),
                remark = routine != null ? "[" + routine.description_chi + "]" + data.remark2 : data.remark2,
                schedule = data.schedule,
                start_date = DateChecking(data.start_date),
                status = (byte)data.status,
                update_user_id = (int)member.infoBySession("id"),
                master_routine_id = data.routine_id
            };

            this._db.recsys_maintenance.AddObject(maintenance);

            try
            {
                this._db.SaveChanges();

                this._db.Refresh(System.Data.Objects.RefreshMode.StoreWins, customerData);
                this._db.Refresh(System.Data.Objects.RefreshMode.StoreWins, maintenance);

                maintenance.customer_id = customerData.id;

                this._db.SaveChanges();

                this._db.Refresh(System.Data.Objects.RefreshMode.StoreWins, maintenance);

                data.id = maintenance.id;
                data.center = customerData.center;

                bool generateOrderYet = data.auto_gen_order.HasValue ? data.auto_gen_order.Value : false;
                if (!generateOrderYet && !string.IsNullOrEmpty(data.confirm_date))
                {
                    IEnumerable<recsys_order> orders;

                    //# logic: create orders (定期保養)
                    if (this.TryGenerateOrdersForMaintenance(maintenance, this._db.recsys_routine.FirstOrDefault(theRoutine => theRoutine.id == maintenance.master_routine_id), out orders))
                    {
                        maintenance.period = orders.Count();
                        maintenance.auto_gen_order = true;

                        this._db.SaveChanges();
                        data.SaveResult.SavedSuccessfully = true;
                    }
                }
                else
                {
                    data.SaveResult.SavedSuccessfully = true;
                }
            }
            catch (OptimisticConcurrencyException)
            {
                //# log down
            }

            return Json(data);
        }