public ActionResult EditSave(CustomerRecord model)
        {
            //# validation
            if (model.id < 0)
                throw new SystemException("Invalid Entity ID");

            if (!String.IsNullOrEmpty(model.name))
            {
                if (model.name.Length > 250)
                {
                    model.SaveResult.WarningMessage = "請修改客戶英文名稱至250字以內";
                    model.SaveResult.SavedSuccessfully = false;
                    return Json(model);
                }
            }
            else
            {
                model.SaveResult.WarningMessage = "請輸入客戶英文名稱";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

            if (!String.IsNullOrEmpty(model.chi_name))
            {
                if (model.chi_name.Length > 250)
                {
                    model.SaveResult.WarningMessage = "請修改客戶中文名稱至250字以內";
                    model.SaveResult.SavedSuccessfully = false;
                    return Json(model);
                }
            }
            else
            {
                model.SaveResult.WarningMessage = "請輸入客戶中文名稱";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

            if (String.IsNullOrEmpty(model.address1))
            {
                model.SaveResult.WarningMessage = "請輸入郵寄地址";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

            if (String.IsNullOrEmpty(model.MailingDistrictName))
            {
                model.SaveResult.WarningMessage = "請輸入郵寄地址地區";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

            //# get old record
            recsys_customers record = this._db.recsys_customers.FirstOrDefault(theCustomer => theCustomer.id == model.id);
            Member member = new Member("users");

            //# validation
            if (record == null)
                throw new RecordNotFoundException();
            if (!record.last_update.HasValue)
                throw new ImproperDataException();
            if (model.FetchRecordTime.CompareTo(record.last_update.Value) < 0)
                throw new OptimisticConcurrencyException("資料已被其他使用者更新");

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

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = model.WorkingDistrictName.Trim(),
                    name = model.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();

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

            createNewDistrict = false;

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

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = model.MailingDistrictName.Trim(),
                    name = model.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();

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

            DateTime nowRef = DateTime.Now;

            //# saving
            //# mapping
            record.address1 = model.address1 ?? "";
            record.address2 = model.address2 ?? "";
            record.center = model.center;
            record.code = model.code;
            record.manual_input_code = model.manual_input_code;
            record.contact = model.contact ?? "";
            record.district1 = model.district1;
            record.district2 = model.district2;
            record.email = model.email ?? "";
            record.fax1 = model.fax1 ?? "";
            record.fax2 = model.fax2 ?? "";
            record.group_id = model.group_id;
            record.id = model.id;
            record.last_update = nowRef.AddMilliseconds(-nowRef.Millisecond);
            record.name = model.name ?? "";
            record.chi_name = model.chi_name ?? "";
            record.prefix = model.prefix ?? "";
            record.reference_number = model.reference_number ?? "";
            record.remark = model.remark ?? "";
            record.status = (byte)(model.status.HasValue ? model.status.Value : 0);
            record.tel1 = model.tel1 ?? "";
            record.tel2 = model.tel2 ?? "";
            record.title = (byte)(model.title.HasValue ? model.title.Value : 0);
            record.type = (byte)(model.type.HasValue ? model.type.Value : 0);
            record.update_user_id = (int)member.infoBySession("id");

            #region Business Logic
            this.CustomerBusinessLogicProcessing(ref record, model.Mode);
            #endregion

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

            return Json(model);
        }
        public ActionResult AddSave(CustomerRecord model)
        {
            Member member = new Member("users");

            //check customer code duplicate
            if (model.type.HasValue)
            {
                if (model.type == (int)CustomerType.Others)
                {
                    string customer_code = model.prefix + model.manual_input_code;
                    var result = this._db.recsys_customers.Where(x => x.customer_code.ToUpper().Equals(customer_code.ToUpper())).SingleOrDefault();

                    if (result != null)
                    {
                        model.SaveResult.WarningMessage = "客戶編號重覆";
                        model.SaveResult.SavedSuccessfully = false;
                        return Json(model);
                    }
                }
            }

            if (!String.IsNullOrEmpty(model.name))
            {
                if (model.name.Length > 250)
                {
                    model.SaveResult.WarningMessage = "請修改客戶英文名稱至250字以內";
                    model.SaveResult.SavedSuccessfully = false;
                    return Json(model);
                }
            }
            else
            {
                model.SaveResult.WarningMessage = "請輸入客戶英文名稱";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

            if (!String.IsNullOrEmpty(model.chi_name))
            {
                if (model.chi_name.Length > 250)
                {
                    model.SaveResult.WarningMessage = "請修改客戶中文名稱至250字以內";
                    model.SaveResult.SavedSuccessfully = false;
                    return Json(model);
                }
            }
            else
            {
                model.SaveResult.WarningMessage = "請輸入客戶中文名稱";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

            if (String.IsNullOrEmpty(model.address1))
            {
                model.SaveResult.WarningMessage = "請輸入郵寄地址";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

            if (String.IsNullOrEmpty(model.MailingDistrictName))
            {
                model.SaveResult.WarningMessage = "請輸入郵寄地址地區";
                model.SaveResult.SavedSuccessfully = false;
                return Json(model);
            }

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

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = model.WorkingDistrictName.Trim(),
                    name = model.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();

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

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

            if (createNewDistrict)
            {
                recsys_district addNewDistrict = new recsys_district()
                {
                    code = model.MailingDistrictName.Trim(),
                    name = model.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();

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

            DateTime nowRef = DateTime.Now;
            //# mapping
            recsys_customers newCustomer = new recsys_customers()
            {
                address1 = model.address1 ?? "",
                address2 = model.address2 ?? "",
                code = model.code,
                contact = model.contact ?? "",
                create_date = nowRef,
                last_update = nowRef.AddMilliseconds(-nowRef.Millisecond),
                center = model.center,
                manual_input_code = model.manual_input_code ?? "",
                district1 = model.district1,
                district2 = model.district2,
                email = model.email ?? "",
                fax1 = model.fax1 ?? "",
                fax2 = model.fax2 ?? "",
                group_id = model.group_id,
                name = model.name ?? "",
                chi_name = model.chi_name ?? "",
                prefix = model.prefix ?? "",
                remark = model.remark ?? "",
                reference_number = model.reference_number ?? "",
                status = (byte)(model.status.HasValue ? model.status.Value : 1),
                tel1 = model.tel1 ?? "",
                tel2 = model.tel2 ?? "",
                title = (byte)(model.title.HasValue ? model.title.Value : 0),
                type = (byte)(model.type.HasValue ? model.type.Value : 0),
                update_user_id = (int) member.infoBySession("id")
            };

            #region Business Logic
            this.CustomerBusinessLogicProcessing(ref newCustomer, model.Mode);
            #endregion

            try
            {
                this._db.recsys_customers.AddObject(newCustomer);
                this._db.SaveChanges();
                this._db.Refresh(System.Data.Objects.RefreshMode.StoreWins, newCustomer);

                model.SaveResult.SavedSuccessfully = true;
                model.id = newCustomer.id;
                model.Mode = PageMode.Edit;         //# after inserted successfully, switch to edit mode
            }
            catch (OptimisticConcurrencyException)
            {
                //# log down
            }

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

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

            //# get old record
            var records = from c in this._db.recsys_customers
                          join u in this._db.recsys_users on c.update_user_id equals u.id into uss
                          from u in uss.DefaultIfEmpty()
                          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 == id
                          select
                          new
                          {
                              c,
                              UpdateUserName = u.name,
                              WorkingDistrictName = d2.name,
                              MailingDistrictName = d1.name
                          };
            var record = records.FirstOrDefault();

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

            model = new CustomerRecord()
            {
                address1 = record.c.address1,
                address2 = record.c.address2,
                code = record.c.code,
                contact = record.c.contact,
                center = record.c.center,
                create_date = record.c.create_date,
                customer_code = record.c.customer_code,
                district1 = record.c.district1,
                district2 = record.c.district2,
                email = record.c.email,
                fax1 = record.c.fax1,
                fax2 = record.c.fax2,
                group_id = record.c.group_id,
                id = record.c.id,
                last_update = record.c.last_update,
                last_update_user_name = record.UpdateUserName,
                name = record.c.name,
                chi_name = record.c.chi_name,
                prefix = record.c.prefix,
                reference_number = record.c.reference_number,
                remark = record.c.remark,
                status = record.c.status,
                tel1 = record.c.tel1,
                tel2 = record.c.tel2,
                title = record.c.title,
                type = record.c.type,
                Mode = PageMode.Edit,
                WorkingDistrictName = record.WorkingDistrictName,
                MailingDistrictName = record.MailingDistrictName
            };

            model.CustomerDataRelatedUpdates = new OrderedDictionary();
            foreach (DictionaryEntry item in this._update)
            {
                int key = Convert.ToInt32(item.Key);
                int num = (from rc in this._db.recsys_relate_customers
                            where rc.customer_id == id && rc.relate_type == key
                            select rc).Count();
                model.CustomerDataRelatedUpdates.Add(item.Key, item.Value + " (" + num + ")");
            }

            model.Districts = this._db.recsys_district
                                                        .Where(theDistrict => theDistrict.status == 1)
                                                        .OrderBy(theDistrict => theDistrict.name);

            model.Groups = this._db.recsys_group
                                                        .Where(theGroup => theGroup.status == 1)
                                                        .OrderBy(theGroup => theGroup.name);

            model.Types = this._type;

            model.Centers = this._ctr;

            model.Titles = this._title;

            model.Statuses = this._status;

            model.Languages = this._lang;

            model.FetchRecordTime = DateTime.Now;

            return View("AddEdit", model);
        }
        public ActionResult Add()
        {
            CustomerRecord model;

            model = new CustomerRecord()
            {
                //# default
                center = Center.Center68.name,
                status = (int) RecordStatus.Active,
                create_date = DateTime.Now,

                //# masters
                DefaultPrefix = "JN",
                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),
                Types = this._type,
                Centers = this._ctr,
                Titles = this._title,
                Statuses = this._status,
                Languages = this._lang,

                //# settings
                Mode = PageMode.Add
            };

            //model.CustomerDataRelatedUpdates = new OrderedDictionary();
            //foreach (DictionaryEntry item in this._update)
            //    model.CustomerDataRelatedUpdates.Add(item.Key, item.Value + " (0)");

            return View("AddEdit", model);
        }