Generate-S1S4FullUatSql.ps1 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. # Generate S1-S4 FULL UAT MySQL write script from dopdemorq extract.
  2. # Usage: .\Generate-S1S4FullUatSql.ps1 -SqlServerPassword '<sa-password>'
  3. param(
  4. [string]$SqlServer = '123.60.180.165',
  5. [string]$SqlUser = 'sa',
  6. [string]$SqlPassword,
  7. [string]$SqlDatabase = 'dopdemorq',
  8. [string]$BillListFile = "$PSScriptRoot\S1S4_FULL_bill_list.txt",
  9. [string]$OutSql = "$PSScriptRoot\..\S1S4_UAT_FULL_execute_write.sql",
  10. [string]$OutTsv = "$PSScriptRoot\..\_extract_full.tsv",
  11. [long]$IdBase = 9106000500000001,
  12. [string]$BatchNo = 'S1S4_UAT_FULL_20260605_V1'
  13. )
  14. $ErrorActionPreference = 'Stop'
  15. if (-not $SqlPassword) { throw 'SqlPassword is required (do not commit to git).' }
  16. function Escape-Sql([string]$s) {
  17. if ($null -eq $s) { return '' }
  18. return ($s -replace "'", "''")
  19. }
  20. $bills = Get-Content $BillListFile | Where-Object { $_.Trim() -ne '' } | ForEach-Object { $_.Trim() }
  21. $billValues = ($bills | ForEach-Object { "(N'$(Escape-Sql $_)')" }) -join ",`n"
  22. $template = Get-Content "$PSScriptRoot\extract_full_from_dopdemorq.sql" -Raw
  23. $extractSql = $template -replace "INSERT INTO @bills\(bill_no\) VALUES \(N'__PLACEHOLDER__'\);", "INSERT INTO @bills(bill_no) VALUES $billValues;"
  24. $extractFile = Join-Path $env:TEMP "s1s4_full_extract.sql"
  25. Set-Content -Path $extractFile -Value $extractSql -Encoding UTF8
  26. $sqlcmd = 'C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\SQLCMD.EXE'
  27. & $sqlcmd -S $SqlServer -U $SqlUser -P $SqlPassword -d $SqlDatabase -i $extractFile -W -h-1 -s"|" -o $OutTsv
  28. if ($LASTEXITCODE -ne 0) { throw "sqlcmd failed with exit $LASTEXITCODE" }
  29. $soRows = @(); $lineRows = @(); $woRows = @()
  30. Get-Content $OutTsv | ForEach-Object {
  31. $line = $_.Trim()
  32. if ($line -eq '' -or $line -match '^-+$' -or $line -match 'rows affected') { return }
  33. $p = $line -split '\|'
  34. if ($p.Count -lt 2) { return }
  35. switch ($p[0]) {
  36. 'SO' { $soRows += [pscustomobject]@{ bill_no=$p[1]; src_id=$p[2]; custom_no=$p[3]; custom_name=$p[4]; order_date=$p[5]; urgent=[int]$p[6] } }
  37. 'LINE' { $lineRows += [pscustomobject]@{ bill_no=$p[1]; src_entry=$p[2]; entry_seq=[int]$p[3]; item_number=$p[4]; qty=$p[5]; plan_date=$p[6] } }
  38. 'WO' { $woRows += [pscustomobject]@{ bill_no=$p[1]; src_entry=$p[2]; morder_no=$p[3]; product_code=$p[4]; need_number=$p[5] } }
  39. }
  40. }
  41. $soByBill = @{}
  42. $idx = 0
  43. foreach ($so in ($soRows | Sort-Object bill_no)) {
  44. if ($soByBill.ContainsKey($so.bill_no)) { continue }
  45. $idx++
  46. $soByBill[$so.bill_no] = [pscustomobject]@{
  47. bill_no = $so.bill_no
  48. target_id = $IdBase + $idx
  49. custom_no = if ($so.custom_no) { $so.custom_no } else { 'CUST0005' }
  50. custom_name = if ($so.custom_name) { $so.custom_name } else { 'WKQXGFYXGE' }
  51. order_date = if ($so.order_date -and $so.order_date -ne 'NULL') { $so.order_date } else { '2025-06-01 00:00:00.000' }
  52. delivery_date = if ($so.order_date -and $so.order_date -ne 'NULL') { $so.order_date } else { '2025-06-15 00:00:00.000' }
  53. urgent = $so.urgent
  54. po_seq = $idx
  55. }
  56. }
  57. $missing = $bills | Where-Object { -not $soByBill.ContainsKey($_) }
  58. Write-Host "Extracted orders: $($soByBill.Count) / $($bills.Count)"
  59. if ($missing.Count -gt 0) { Write-Host "Missing in dopdemorq: $($missing -join ', ')" }
  60. $lineIdx = 0; $moIdx = 0; $linesOut = @(); $mosOut = @(); $prsOut = @(); $poLinesOut = @()
  61. $woByEntry = @{}
  62. foreach ($w in $woRows) { $woByEntry[$w.src_entry] = $w }
  63. foreach ($bill in ($soByBill.Keys | Sort-Object)) {
  64. $so = $soByBill[$bill]
  65. $lines = $lineRows | Where-Object { $_.bill_no -eq $bill } | Sort-Object entry_seq, src_entry
  66. $poNo = ('PO-UAT-FULL-20260605-{0:D3}' -f $so.po_seq)
  67. $prSeq = 0
  68. $poLineNo = 0
  69. foreach ($ln in $lines) {
  70. $lineIdx++
  71. $targetLine = $IdBase + 10000 + $lineIdx
  72. $planDt = if ($ln.plan_date -and $ln.plan_date -ne 'NULL') { $ln.plan_date } else { $so.order_date }
  73. $linesOut += "($targetLine,'$(Escape-Sql $ln.src_entry)','$($so.bill_no)',$($ln.entry_seq),'$(Escape-Sql $ln.item_number)',$($ln.qty),'$planDt')"
  74. $wo = $woByEntry[$ln.src_entry]
  75. if ($wo) {
  76. $moIdx++
  77. $targetMo = $IdBase + 20000 + $moIdx
  78. $targetMe = $IdBase + 40000 + $moIdx
  79. $mosOut += "($targetMo,$targetMe,'$(Escape-Sql $ln.src_entry)','$($so.bill_no)','$(Escape-Sql $wo.morder_no)','$(Escape-Sql $wo.product_code)',$($wo.need_number))"
  80. $prSeq++
  81. $prBill = 'PR-UAT-FULL-20260605-{0:D3}' -f $prSeq
  82. $prsOut += "($($IdBase + 50000 + $moIdx),'$prBill','$(Escape-Sql $wo.morder_no)','$($so.bill_no)','$(Escape-Sql $wo.product_code)',$($wo.need_number),$targetMo)"
  83. $poLineNo++
  84. $poLinesOut += "('$poNo',$poLineNo,'$($so.bill_no)','$(Escape-Sql $wo.morder_no)','$(Escape-Sql $ln.item_number)',$($ln.qty))"
  85. }
  86. }
  87. if ($poLineNo -eq 0 -and $lines.Count -gt 0) {
  88. $ln = $lines[0]
  89. $moIdx++
  90. $synMo = "UAT-MO-$($so.po_seq.ToString('D4'))"
  91. $targetMo = $IdBase + 20000 + $moIdx
  92. $targetMe = $IdBase + 40000 + $moIdx
  93. $mosOut += "($targetMo,$targetMe,'$(Escape-Sql $ln.src_entry)','$($so.bill_no)','$synMo','$(Escape-Sql $ln.item_number)',$($ln.qty))"
  94. $prBill = 'PR-UAT-FULL-20260605-001'
  95. $prsOut += "($($IdBase + 50000 + $moIdx),'$prBill','$synMo','$($so.bill_no)','$(Escape-Sql $ln.item_number)',$($ln.qty),$targetMo)"
  96. $poLinesOut += "('$poNo',1,'$($so.bill_no)','$synMo','$(Escape-Sql $ln.item_number)',$($ln.qty))"
  97. }
  98. }
  99. $soIns = ($soByBill.Values | Sort-Object target_id | ForEach-Object {
  100. "('$($_.bill_no)',$($_.target_id),'$(Escape-Sql $_.custom_no)','$(Escape-Sql $_.custom_name)','$($_.order_date)','$($_.delivery_date)',$($_.urgent))"
  101. }) -join ",`n"
  102. $shipIns = ($soByBill.Values | Sort-Object po_seq | ForEach-Object {
  103. $shipId = $IdBase + 60000 + $_.po_seq
  104. $poNo = ('PO-UAT-FULL-20260605-{0:D3}' -f $_.po_seq)
  105. $shNo = ('SH-UAT-FULL-20260605-{0:D3}' -f $_.po_seq)
  106. "($shipId,'$poNo','$shNo')"
  107. }) -join ",`n"
  108. $header = @"
  109. -- S1-S4 FULL UAT write (AIDOP tenant 797403760988229)
  110. -- Batch: $BatchNo
  111. -- Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
  112. -- Orders: $($soByBill.Count)
  113. SET @tenant_id := 797403760988229;
  114. SET @batch_no := '$BatchNo';
  115. SET @operator_id := 1300000000111;
  116. SET @operator_name := 'UAT数据导入';
  117. SET @now := NOW();
  118. SET @factory_id := 797403760988229;
  119. SET @id_base := $IdBase;
  120. DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so;
  121. CREATE TEMPORARY TABLE tmp_s1_uat_so (
  122. bill_no VARCHAR(64) NOT NULL PRIMARY KEY,
  123. target_id BIGINT NOT NULL,
  124. custom_no VARCHAR(64) NULL,
  125. custom_name VARCHAR(128) NULL,
  126. order_date DATETIME NULL,
  127. delivery_date DATETIME NULL,
  128. urgent INT DEFAULT 0
  129. );
  130. INSERT INTO tmp_s1_uat_so VALUES
  131. $soIns;
  132. DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so_line;
  133. CREATE TEMPORARY TABLE tmp_s1_uat_so_line (
  134. target_id BIGINT NOT NULL PRIMARY KEY,
  135. source_entry VARCHAR(32) NOT NULL,
  136. bill_no VARCHAR(64) NOT NULL,
  137. entry_seq INT NOT NULL,
  138. item_number VARCHAR(64) NULL,
  139. qty DECIMAL(18,4) NULL,
  140. plan_date DATETIME NULL
  141. );
  142. INSERT INTO tmp_s1_uat_so_line VALUES
  143. $($linesOut -join ",`n");
  144. DROP TEMPORARY TABLE IF EXISTS tmp_s2_uat_morder;
  145. CREATE TEMPORARY TABLE tmp_s2_uat_morder (
  146. target_mo_id BIGINT NOT NULL PRIMARY KEY,
  147. target_me_id BIGINT NOT NULL,
  148. source_entry VARCHAR(32) NOT NULL,
  149. bill_no VARCHAR(64) NOT NULL,
  150. morder_no VARCHAR(128) NOT NULL,
  151. product_code VARCHAR(128) NULL,
  152. need_number DECIMAL(23,10) NULL
  153. );
  154. INSERT INTO tmp_s2_uat_morder VALUES
  155. $($mosOut -join ",`n");
  156. DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_pr;
  157. CREATE TEMPORARY TABLE tmp_s3_uat_pr (
  158. voucher BIGINT NOT NULL PRIMARY KEY,
  159. pr_billno VARCHAR(64) NOT NULL,
  160. morder_no VARCHAR(128) NOT NULL,
  161. bill_no VARCHAR(64) NOT NULL,
  162. icitem_code VARCHAR(64) NULL,
  163. pr_rqty DECIMAL(18,4) NULL,
  164. mo_id BIGINT NOT NULL
  165. );
  166. INSERT INTO tmp_s3_uat_pr VALUES
  167. $($prsOut -join ",`n");
  168. DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_line;
  169. CREATE TEMPORARY TABLE tmp_s3_uat_po_line (
  170. pur_ord VARCHAR(48) NOT NULL,
  171. line_no INT NOT NULL,
  172. sales_ord VARCHAR(64) NOT NULL,
  173. work_ord VARCHAR(128) NULL,
  174. item_num VARCHAR(60) NOT NULL,
  175. qty DECIMAL(15,5) NOT NULL,
  176. PRIMARY KEY (pur_ord, line_no)
  177. );
  178. INSERT INTO tmp_s3_uat_po_line VALUES
  179. $($poLinesOut -join ",`n");
  180. DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_hdr;
  181. CREATE TEMPORARY TABLE tmp_s3_uat_po_hdr (
  182. pur_ord VARCHAR(48) NOT NULL PRIMARY KEY,
  183. sales_ord VARCHAR(64) NOT NULL,
  184. work_ord VARCHAR(128) NULL
  185. );
  186. INSERT INTO tmp_s3_uat_po_hdr
  187. SELECT pur_ord, MIN(sales_ord), MIN(work_ord) FROM tmp_s3_uat_po_line GROUP BY pur_ord;
  188. DROP TEMPORARY TABLE IF EXISTS tmp_s4_uat_ship;
  189. CREATE TEMPORARY TABLE tmp_s4_uat_ship (
  190. ship_id BIGINT NOT NULL PRIMARY KEY,
  191. po_billno VARCHAR(48) NOT NULL,
  192. shddh VARCHAR(64) NOT NULL
  193. );
  194. INSERT INTO tmp_s4_uat_ship VALUES
  195. $shipIns;
  196. "@
  197. $body = Get-Content "$PSScriptRoot\S1S4_UAT_FULL_write_body.sql" -Raw -ErrorAction SilentlyContinue
  198. if (-not $body) {
  199. $body = Get-Content "$PSScriptRoot\..\S1S4_UAT_P0_execute_write.sql" -Raw
  200. $start = $body.IndexOf('START TRANSACTION;')
  201. $body = $body.Substring($start)
  202. $body = $body -replace 'PR-UAT-20260604-', 'PR-UAT-FULL-20260605-'
  203. $body = $body -replace 'PO-UAT-20260604-', 'PO-UAT-FULL-20260605-'
  204. $body = $body -replace 'SH-UAT-20260604-', 'SH-UAT-FULL-20260605-'
  205. $body = $body -replace "CONCAT\('UAT导入:', @batch_no\)", "CONCAT('UAT导入:', @batch_no)"
  206. $body = $body -replace "Remark, CONCAT\('UAT:', @batch_no\)", "Remark, CONCAT('UAT:', @batch_no)"
  207. }
  208. Set-Content -Path $OutSql -Value ($header + $body) -Encoding UTF8
  209. Write-Host "Wrote $OutSql"