diff --git a/AMESCoreStudio.WebApi/Controllers/AMES/SNKeyPartsController.cs b/AMESCoreStudio.WebApi/Controllers/AMES/SNKeyPartsController.cs
new file mode 100644
index 00000000..46285f25
--- /dev/null
+++ b/AMESCoreStudio.WebApi/Controllers/AMES/SNKeyPartsController.cs
@@ -0,0 +1,243 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using AMESCoreStudio.WebApi;
+using AMESCoreStudio.WebApi.Models.AMES;
+using AMESCoreStudio.CommonTools.Result;
+
+namespace AMESCoreStudio.WebApi.Controllers.AMES
+{
+ ///
+ /// 外包機種資料維護
+ ///
+ [Route("api/[controller]")]
+ [ApiController]
+ public class SNKeyPartsController : ControllerBase
+ {
+ private readonly AMESContext _context;
+
+ ///
+ ///
+ ///
+ ///
+ public SNKeyPartsController(AMESContext context)
+ {
+ _context = context;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ // GET: api/SNKeyParts
+ [HttpGet]
+ public async Task>> GetSNKeyPart(int page = 0, int limit = 10)
+ {
+ IQueryable q = _context.SNKeyParts;
+ if (page > 0)
+ {
+ q = q.OrderBy(p => p.StockInNo + p.KPItem).Skip((page - 1) * limit).Take(limit);
+ }
+ else
+ {
+ q = q.OrderBy(p => p.StockInNo + p.KPItem);
+ }
+
+ var snKeyPart = await q.ToListAsync();
+ return snKeyPart;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ // GET: api/SNKeyParts/StockInNo/S
+ [HttpGet("StockInNo/{no}")]
+ public async Task>> GetSNKeyPartByStockInNo(string no,int page = 0, int limit = 10)
+ {
+ IQueryable q = _context.SNKeyParts;
+
+ if (no != null)
+ {
+ if (no != "*")
+ {
+ q = q.Where(p => p.StockInNo.Equals(no));
+ }
+ }
+
+ if (page > 0)
+ {
+ q = q.OrderBy(p => p.StockInNo + p.KPItem).Skip((page - 1) * limit).Take(limit);
+ }
+ else
+ {
+ q = q.OrderBy(p => p.StockInNo + p.KPItem);
+ }
+
+ var snKeyPart = await q.ToListAsync();
+ return snKeyPart;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ // GET: api/SNKeyParts/5
+ [HttpGet("{id}")]
+ public async Task>> GetSNKeyPart(string id)
+ {
+ string[] param = id.Split(',');
+ string stockInNo = param[0];
+ int kpItem = int.Parse(param[1]);
+
+ IQueryable q = _context.SNKeyParts;
+ q = q.Where(p => p.StockInNo.Equals(stockInNo) && p.KPItem.Equals(kpItem));
+
+ var snKeyPart = await q.ToListAsync();
+
+ if (snKeyPart == null)
+ {
+ return NotFound();
+ }
+
+ return snKeyPart;
+ }
+
+ ///
+ /// 修改外包機種資料
+ ///
+ ///
+ ///
+ ///
+ // PUT: api/SNKeyParts/5
+ // To protect from overposting attacks, enable the specific properties you want to bind to, for
+ // more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
+ [HttpPut("{id}")]
+ public async Task> PutSNKeyPart(string id, SNKeyPart sNKeyPart)
+ {
+ ResultModel result = new ResultModel();
+
+ string[] param = id.Split(',');
+ string stockInNo = param[0];
+ int kpItem = int.Parse(param[1]);
+
+ if (stockInNo != sNKeyPart.StockInNo)
+ {
+ result.Success = false;
+ result.Msg = "入庫單號錯誤";
+ return result;
+ }
+
+ if (kpItem != sNKeyPart.KPItem)
+ {
+ result.Success = false;
+ result.Msg = "入庫單號項次錯誤";
+ return result;
+ }
+
+ _context.Entry(sNKeyPart).State = EntityState.Modified;
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!SNKeyPartExists(stockInNo,kpItem))
+ {
+ result.Success = false;
+ result.Msg = "入庫單號&項次錯誤";
+ return result;
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ result.Success = true;
+ result.Msg = "OK";
+ return result;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ // POST: api/SNKeyParts
+ // To protect from overposting attacks, enable the specific properties you want to bind to, for
+ // more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
+ [HttpPost]
+ public async Task> PostSNKeyPart(SNKeyPart sNKeyPart)
+ {
+ ResultModel result = new ResultModel();
+
+ if (SNKeyPartExists(sNKeyPart.StockInNo, sNKeyPart.KPItem))
+ {
+ result.Success = false;
+ result.Msg = "資料重複:"+ sNKeyPart.StockInNo+","+ sNKeyPart.KPItem;
+ return result;
+ }
+
+ _context.SNKeyParts.Add(sNKeyPart);
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateException)
+ {
+
+ }
+
+ result.Success = true;
+ result.Msg = "OK";
+ return result;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ // DELETE: api/SNKeyParts/5
+ [HttpDelete("{id}")]
+ public async Task> DeleteSNKeyPart(string id)
+ {
+ ResultModel result = new ResultModel();
+
+ string[] param = id.Split(',');
+ string stockInNo = param[0];
+ int kpItem = int.Parse(param[1]);
+
+ var snKeyPart = await _context.SNKeyParts.Where(p => p.StockInNo == stockInNo && p.KPItem == kpItem).FirstOrDefaultAsync();
+
+ if (snKeyPart == null)
+ {
+ result.Success = false;
+ result.Msg = "資料不存在";
+ return result;
+ }
+
+ _context.SNKeyParts.Remove(snKeyPart);
+ await _context.SaveChangesAsync();
+
+ result.Success = true;
+ result.Msg = "OK";
+ return result;
+ }
+
+ private bool SNKeyPartExists(string stockInNo,int kpItem)
+ {
+ return _context.SNKeyParts.Any(e => e.StockInNo == stockInNo && e.KPItem == kpItem);
+ }
+ }
+}
diff --git a/AMESCoreStudio.WebApi/Models/AMES/SNKeyPart.cs b/AMESCoreStudio.WebApi/Models/AMES/SNKeyPart.cs
new file mode 100644
index 00000000..28cf912c
--- /dev/null
+++ b/AMESCoreStudio.WebApi/Models/AMES/SNKeyPart.cs
@@ -0,0 +1,100 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Runtime.Serialization;
+
+namespace AMESCoreStudio.WebApi.Models.AMES
+{
+ ///
+ /// 外包機種資料
+ ///
+ [Table("SN_KEYPART", Schema = "JHAMES")]
+ [DataContract]
+ public class SNKeyPart
+ {
+ ///
+ /// 入庫單號
+ ///
+ [Key]
+ [Column("STOCK_IN_NO")]
+ [Required(ErrorMessage = "{0},不能空白")]
+ [DataMember]
+ public string StockInNo { get; set; }
+
+ ///
+ /// 入庫料號
+ ///
+ [Column("STOCK_IN_PN")]
+ [DataMember]
+ [Required(ErrorMessage = "{0},不能空白")]
+ [Display(Name = "入庫料號")]
+ public string StockInPn { get; set; }
+
+ ///
+ /// 組件日期
+ ///
+ [Column("KP_DATE")]
+ [DataMember]
+ [Display(Name = "組件日期")]
+ public DateTime KPDate { get; set; }
+
+ ///
+ /// 組件序號
+ ///
+ [Key]
+ [Column("KP_ITEM")]
+ [DataMember]
+ [Display(Name = "組件序號")]
+ public int KPItem { get; set; }
+
+ ///
+ /// 組件SN
+ ///
+ [Column("KP_SN")]
+ [DataMember]
+ [Required(ErrorMessage = "{0},不能空白")]
+ [Display(Name = "組件SN")]
+ public string KPSn { get; set; }
+
+ ///
+ /// 組件MB
+ ///
+ [Column("KP_MB")]
+ [DataMember]
+ [Required(ErrorMessage = "{0},不能空白")]
+ [Display(Name = "組件MB")]
+ public string KPMb { get; set; }
+
+ ///
+ /// 組件MAC
+ ///
+ [Column("KP_MAC")]
+ [DataMember]
+ [Display(Name = "組件MAC")]
+ public string KPMac { get; set; }
+
+ ///
+ /// 組件Panel
+ ///
+ [Column("KP_PANEL")]
+ [DataMember]
+ [Display(Name = "組件Panel")]
+ public string KPPanel { get; set; }
+
+ ///
+ /// 建立者
+ ///
+ [Column("CREATE_USERID")]
+ [DataMember]
+ [Display(Name = "建立者")]
+ public int CreateUserID { get; set; } = 0;
+
+ ///
+ /// 建立日期
+ ///
+ [Column("CREATE_DATE")]
+ [DataMember]
+ [Display(Name = "建立日期")]
+ public DateTime CreateDate { get; set; } = DateTime.Now;
+ }
+}