BOM script produces links to parts

This commit is contained in:
Matt McWilliams 2024-11-28 14:43:06 -05:00
parent 1d2a65867b
commit 6d99122a33
10 changed files with 184 additions and 54 deletions

View File

@ -1,13 +1,13 @@
module,quantity,part,part_id,description
front_block_pegs,2,M2.5 hex cap bolts 10mm,N/A,Fasctens front_block_pegs to front_block
front_block_pegs,2,M2.5 hex cap bolt 10mm,N/A,Fasctens front_block_pegs to front_block
front_block,4,M2.5 hex nut,N/A,Attach the film path blocks
front_block,2,M5 hex cap bolt 25mm,N/A,Attach the front_block to the body
body,2,Bearing,N/A,Center sprocketed_roller in gate voids and allow for smooth rotation
body,2,608-RS Ball Bearing,608-RS,Center sprocketed_roller in gate voids and allow for smooth rotation
body,2,M3 hex nut,N/A,Attach slide_catch to gate
body,12,M2.5 hex nut,ISO 4032,Attach idle_roller and filter_holder and slide_rail to gate
body,4,M2.5 hex cap bolt 10mm,N/A,Attach slide_rail to gate
body,2,M2.5 hex cap bolt 25mm,N/A,Attach filter_holder to gate
body,6,M2.5 hex cap bolt 15mm,N/A,Attach idle_roller to gate
body,6,M2.5 hex cap bolt 16mm,N/A,Attach idle_roller to gate
body,2,M5 hex nut,N/A,Attach front_block to gate
body,2,M5 hex cap bolt 20mm,N/A,Attach gate to projector
sprocketed_roller_nut_16mm,2,M2.5 hex nut,ISO 4032,Attaches the bolt to the nut

1 module quantity part part_id description
2 front_block_pegs 2 M2.5 hex cap bolts 10mm M2.5 hex cap bolt 10mm N/A Fasctens front_block_pegs to front_block
3 front_block 4 M2.5 hex nut N/A Attach the film path blocks
4 front_block 2 M5 hex cap bolt 25mm N/A Attach the front_block to the body
5 body 2 Bearing 608-RS Ball Bearing N/A 608-RS Center sprocketed_roller in gate voids and allow for smooth rotation
6 body 2 M3 hex nut N/A Attach slide_catch to gate
7 body 12 M2.5 hex nut ISO 4032 Attach idle_roller and filter_holder and slide_rail to gate
8 body 4 M2.5 hex cap bolt 10mm N/A Attach slide_rail to gate
9 body 2 M2.5 hex cap bolt 25mm N/A Attach filter_holder to gate
10 body 6 M2.5 hex cap bolt 15mm M2.5 hex cap bolt 16mm N/A Attach idle_roller to gate
11 body 2 M5 hex nut N/A Attach front_block to gate
12 body 2 M5 hex cap bolt 20mm N/A Attach gate to projector
13 sprocketed_roller_nut_16mm 2 M2.5 hex nut ISO 4032 Attaches the bolt to the nut

View File

@ -1,13 +1,11 @@
quantity,part_id,part,price
2,"M5 hex nut",N/A,0
2,"M5 hex cap bolt 25mm",N/A,0
2,"M5 hex cap bolt 20mm",N/A,0
2,"M3 hex nut",N/A,6
19,"M2.5 hex nut",N/A,171
2,"M2.5 hex cap bolts 10mm",N/A,0
2,"M2.5 hex cap bolt 25mm",N/A,0
2,"M2.5 hex cap bolt 16mm","ISO 4762",0
6,"M2.5 hex cap bolt 15mm",N/A,0
5,"M2.5 hex cap bolt 10mm",N/A,0
2,Bearing,N/A,0
46,N/A,TOTALS,177
quantity,part,part_id,price
2,"M5 hex nut",N/A,10
2,"M5 hex cap bolt 25mm",N/A,54
2,"M5 hex cap bolt 20mm",N/A,38
2,"M3 hex nut",N/A,7
19,"M2.5 hex nut",N/A,120
2,"M2.5 hex cap bolt 25mm",N/A,12
8,"M2.5 hex cap bolt 16mm",N/A,112
7,"M2.5 hex cap bolt 10mm",N/A,98
2,"608-RS Ball Bearing",608-RS,36
46,TOTAL,N/A,487

1 quantity part part_id price
2 2 N/A M5 hex nut M5 hex nut N/A 0 10
3 2 N/A M5 hex cap bolt 25mm M5 hex cap bolt 25mm N/A 0 54
4 2 N/A M5 hex cap bolt 20mm M5 hex cap bolt 20mm N/A 0 38
5 2 N/A M3 hex nut M3 hex nut N/A 6 7
6 19 N/A M2.5 hex nut M2.5 hex nut N/A 171 120
7 2 N/A M2.5 hex cap bolt 25mm M2.5 hex cap bolts 10mm N/A 0 12
8 2 8 N/A M2.5 hex cap bolt 16mm M2.5 hex cap bolt 25mm N/A 0 112
9 2 7 ISO 4762 M2.5 hex cap bolt 10mm M2.5 hex cap bolt 16mm N/A 0 98
10 6 2 N/A 608-RS Ball Bearing M2.5 hex cap bolt 15mm 608-RS 0 36
11 5 46 N/A TOTAL M2.5 hex cap bolt 10mm N/A 0 487
2 N/A Bearing 0
46 TOTALS N/A 177

View File

@ -1,4 +1,4 @@
module,quantity,part,part_id,description
sled,8,Radial bearing,N/A,For something
sled,8,608-RS Ball Bearing,608-RS,To smooth sled moving along rails
sled,2,Linear bearing,N/A,For center rails
sled,2,T8 Nut,N/A,For drive screw
sled,2,T8 Nut,Tr8x2,For drive screw

1 module quantity part part_id description
2 sled 8 Radial bearing 608-RS Ball Bearing N/A 608-RS For something To smooth sled moving along rails
3 sled 2 Linear bearing N/A For center rails
4 sled 2 T8 Nut N/A Tr8x2 For drive screw

View File

@ -1,5 +1,5 @@
quantity,part_id,part,price
2,"T8 Nut",N/A,0
8,"Radial bearing",N/A,0
2,"Linear bearing",N/A,0
12,N/A,TOTALS,0
quantity,part,part_id,price
2,"T8 Nut",Tr8x2,499
2,"Linear bearing",N/A,200
8,"608-RS Ball Bearing",608-RS,143
12,TOTAL,N/A,842

1 quantity part part_id price
2 2 N/A T8 Nut T8 Nut Tr8x2 0 499
3 8 2 N/A Linear bearing Radial bearing N/A 0 200
4 2 8 N/A 608-RS Ball Bearing Linear bearing 608-RS 0 143
5 12 TOTALS TOTAL N/A 0 842

View File

@ -1,5 +1,23 @@
part,part_id,price,url
M3 hex nut,N/A,3,https://amzn.to/4hAnwjc
M3 hex cap bolt 12mm,N/A,9,https://amzn.to/48CGa5Y
608-RS Ball Bearing,608-RS,8,https://amzn.to/4fKxDA7
M2.5 hex nut, ISO 4032,9,https://www.metricscrewandtool.com/product-page/m2-5-hex-nuts
part,part_id,price,quantity,url
M3 hex nut,N/A,999,300,https://amzn.to/4hAnwjc
M2.5 hex nut,ISO 4032,629,100,https://amzn.to/4i7qxrr
M2.5 hex cap bolt 10mm,N/A,699,50,https://amzn.to/49froT4
M2.5 hex cap bolt 16mm,N/A,699,50,https://amzn.to/49cj6v2
M2.5 hex cap bolt 25mm,N/A,598,100,https://amzn.to/41faYb0
M3 hex cap bolt 6mm,N/A,726,100,https://amzn.to/3AwiZxo
M3 hex cap bolt 8mm,N/A,899,100,https://amzn.to/3YEvWNB
M3 hex cap bolt 12mm,N/A,836,100,https://amzn.to/48CGa5Y
M3 sliding t slot nut,N/A,599,105,https://amzn.to/48GRrSU
M5 hex cap bolt 20mm,N/A,949,50,https://amzn.to/4ePHCmW
M5 hex cap bolt 25mm,N/A,809,30,https://amzn.to/3VgdQAW
M5 hex nut,N/A,999,200,https://amzn.to/3ZdMNHs
2020 Aluminum extrusion mm,N/A,7399,12200,https://amzn.to/418OicC
100RPM DC geared motor with encoder,N/A,1619,1,https://amzn.to/3UF707G
250RPM DC geared motor,JSX40-370,1499,1,https://amzn.to/3NWkcRL
ESP32 Dev board,N/A,1999,3,https://amzn.to/3NXCvGj
L298N Motor driver module,N/A,1149,4,https://amzn.to/4ellssy
ESP32 GPIO breakout board,N/A,1199,2,https://amzn.to/3UFjpbO
M4 hex bolt 40mm,N/A,609,10,https://amzn.to/4ikpYL8
608-RS Ball Bearing,608-RS,1779,100,https://amzn.to/4fKxDA7
Linear bearing,LM8UU,1199,12,https://amzn.to/4i5XsMZ
T8 Nut,Tr8x2,499,2,https://amzn.to/3B4m4VW
1 part part_id price quantity url
2 M3 hex nut N/A 3 999 300 https://amzn.to/4hAnwjc
3 M3 hex cap bolt 12mm M2.5 hex nut N/A ISO 4032 9 629 100 https://amzn.to/48CGa5Y https://amzn.to/4i7qxrr
4 608-RS Ball Bearing M2.5 hex cap bolt 10mm 608-RS N/A 8 699 50 https://amzn.to/4fKxDA7 https://amzn.to/49froT4
5 M2.5 hex nut M2.5 hex cap bolt 16mm ISO 4032 N/A 9 699 50 https://www.metricscrewandtool.com/product-page/m2-5-hex-nuts https://amzn.to/49cj6v2
6 M2.5 hex cap bolt 25mm N/A 598 100 https://amzn.to/41faYb0
7 M3 hex cap bolt 6mm N/A 726 100 https://amzn.to/3AwiZxo
8 M3 hex cap bolt 8mm N/A 899 100 https://amzn.to/3YEvWNB
9 M3 hex cap bolt 12mm N/A 836 100 https://amzn.to/48CGa5Y
10 M3 sliding t slot nut N/A 599 105 https://amzn.to/48GRrSU
11 M5 hex cap bolt 20mm N/A 949 50 https://amzn.to/4ePHCmW
12 M5 hex cap bolt 25mm N/A 809 30 https://amzn.to/3VgdQAW
13 M5 hex nut N/A 999 200 https://amzn.to/3ZdMNHs
14 2020 Aluminum extrusion mm N/A 7399 12200 https://amzn.to/418OicC
15 100RPM DC geared motor with encoder N/A 1619 1 https://amzn.to/3UF707G
16 250RPM DC geared motor JSX40-370 1499 1 https://amzn.to/3NWkcRL
17 ESP32 Dev board N/A 1999 3 https://amzn.to/3NXCvGj
18 L298N Motor driver module N/A 1149 4 https://amzn.to/4ellssy
19 ESP32 GPIO breakout board N/A 1199 2 https://amzn.to/3UFjpbO
20 M4 hex bolt 40mm N/A 609 10 https://amzn.to/4ikpYL8
21 608-RS Ball Bearing 608-RS 1779 100 https://amzn.to/4fKxDA7
22 Linear bearing LM8UU 1199 12 https://amzn.to/4i5XsMZ
23 T8 Nut Tr8x2 499 2 https://amzn.to/3B4m4VW

View File

@ -368,7 +368,7 @@ module sprocketed_roller_text (pos = [0, 0, 0], rot = [0, 0, 0], font_size = 3,
translate(pos) rotate(rot) {
for (i = [0 : chars_len - 1]) {
rotate(-i * step_angle) {
translate([0, radius + font_size / 2, 0]) {
translate([0, radius + font_size / 2, 0]) rotate([180, 0, 0]) {
linear_extrude(height = h) {
text(chars[i], font = "Liberation Sans:style=Bold", size = font_size, valign = "center", halign = "center");
}
@ -410,7 +410,7 @@ module sprocketed_roller_16mm (pos = [0, 0, 0], rot = [0, 0, 0], side = "TAKEUP"
//m2.5 bolt
translate([0, 0, -15.85]) rotate([0, 90, 0]) cylinder(r = R(2.75), h = 30, center = true, $fn = 30);
//
sprocketed_roller_text([0, 0, 16], chars = side);
sprocketed_roller_text([0, 0, -1], chars = side);
}
}
@ -447,12 +447,12 @@ module sprocketed_roller_nut_16mm (pos = [0, 0, 0], rot = [0, 0, 0]) {
//BOM: 2, M5 hex cap bolt 20mm, N/A, Attach gate to projector
//BOM: 2, M5 hex nut, N/A, Attach front_block to gate
//BOM: 6, M2.5 hex cap bolt 15mm, N/A, Attach idle_roller to gate
//BOM: 6, M2.5 hex cap bolt 16mm, N/A, Attach idle_roller to gate
//BOM: 2, M2.5 hex cap bolt 25mm, N/A, Attach filter_holder to gate
//BOM: 4, M2.5 hex cap bolt 10mm, N/A, Attach slide_rail to gate
//BOM: 12, M2.5 hex nut, ISO 4032, Attach idle_roller and filter_holder and slide_rail to gate
//BOM: 2, M3 hex nut, N/A, Attach slide_catch to gate
//BOM: 2, Bearing, N/A, Center sprocketed_roller in gate voids and allow for smooth rotation
//BOM: 2, 608-RS Ball Bearing, 608-RS, Center sprocketed_roller in gate voids and allow for smooth rotation
module body (pos = [0, 0, 0], gauge = "16mm") {
SlideRailsOffsetZ = -5;
translate(pos) {
@ -770,7 +770,7 @@ module front_block_peg (pos = [0, 0, 0], rot = [0, 0, 0], h = 10) {
}
}
//BOM: 2, M2.5 hex cap bolts 10mm, N/A, Fasctens front_block_pegs to front_block
//BOM: 2, M2.5 hex cap bolt 10mm, N/A, Fasctens front_block_pegs to front_block
module front_block_pegs (pos = [0, 0, 0], rot = [0, 0, 0]) {
PegSpacingY = 24.2;
BoltSpacingY = 24;
@ -822,18 +822,29 @@ module filter_block (pos = [0, 0, 0], rot = [0, 0, 0], side = "A") {
}
}
module debug_film (pos = [0, 0, 0]) {
color("blue") translate(pos) {
difference () {
16mm_film(18, true, true);
translate([0, -7.49 / 2, 0]) cube([10.26, 7.49, 1], center = true);
}
}
}
module debug () {
FilmRestingDistanceZ = -3.5;
FilmRetractionDistanceZ = -7.2;
difference () {
//color("blue") translate([8, 4.6, FilmZ]) 16mm_film(18, true, true);
union () {
FilmZ = - 7.2; //retraction distance
FilmZ = FilmRestingDistanceZ; //retraction distance
translate([(-BodyX / 2) - 1, 0, -BodyZ / 2]) body(gauge = "16mm");
debug_film([8, 4.6, FilmZ]);
translate([0, 0, FilmZ + 1.4]) front_plate();
translate([0, 0, FilmZ - 1.4]) back_plate();
//gate_mask_slide_standard16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]);
gate_mask_slide_super16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]);
gate_mask_slide_standard16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]);
//gate_mask_slide_super16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]);
//front_plate_void([(PlateX / 2) - (FrontPlateVoidX / 2) - 2.41, 0, 0]);
//film_clearance_void([0, 0, 15]);
@ -874,7 +885,7 @@ module debug () {
}
}
PART="front_block_16mmx";
PART="sprocketed_roller_takeup_16mmx";
if (PART == "front_plate") {
//1

View File

@ -93,15 +93,22 @@ module m3BoltNut (bolt = 20, nut = 3.5) {
}
}
module m4BoltNut (bolt = 10, nut = 3.5) {
module m4BoltNut (bolt = 10, nut = 3.5, drop = true) {
m4Bolt(bolt);
translate([0, 0, nut]) color("red") {
m4_nut();
translate([-10, 0, 0]) cube([20, 6.9, 3.5], center = true);
m4_nut(3.5);
if (drop) {
translate([-10, 0, 0]) cube([20, 6.9, 3.5], center = true);
}
}
}
module m5Nut () {
cylinder(r = R(9), h = 4, center = true, $fn = 6);
cylinder(r = R(5), h = 20, center = true, $fn = 30);
}
module lensAssembyBellowBoardLinearBearingMount (X = 0) {
difference () {
translate([X, XOffset, FrontOffset]) rotate([0, 90, 0]) cylinder(r = R(25), h = 24, center = true, $fn = 80);
@ -385,7 +392,7 @@ module jkLensLinearRodTerminalBlock (pos = [0, 0, 0]) {
translate(pos) difference() {
cube([26.5, 20, 15], center = true);
cylinder(r = 8.1 / 2, h = 15 + 1, center = true, $fn = 50);
translate([12, 0, 0]) rotate([0, 90, 180]) m4BoltNut(20);
translate([5, 0, 0]) rotate([0, -90, 180]) m4BoltNut(20);
}
}
@ -394,6 +401,7 @@ module jkLensMount () {
BoltSpacingX = 78.5 + 5.3;
BoltD = 4.25;
RailsY = -32;
difference () {
union() {
cube([140, 15.5, 3], center = true);
@ -409,24 +417,62 @@ module jkLensMount () {
translate([-130 / 2, -25, 4]) cube([26.5, 40, 5], center = true);
//linear rod terminal block
jkLensLinearRodTerminalBlock([130 / 2, -32, 14]);
jkLensLinearRodTerminalBlock([130 / 2, -32, 14 - 20]);
//threaded rod bearing block
translate([-130 / 2, -32, 12]) cylinder(r = 22.5 / 2, h = 20, center = true, $fn = 90);
translate([-130 / 2, -32, 12 - 20]) cylinder(r = 22.5 / 2, h = 22, center = true, $fn = 90);
}
}
translate([73.25, -32, 14 - 5]) cylinder(r = 8.1 / 2, h = 20, center = true, $fn = 50);
translate([BoltSpacingX / 2, 0, 0]) cylinder( r = BoltD / 2, h = 20, center = true, $fn = 30);
translate([-BoltSpacingX / 2, 0, 0]) cylinder( r = BoltD / 2, h = 20, center = true, $fn = 30);
translate([-BoltSpacingX / 2, 0, 14.5]) cylinder( r = 8/ 2, h = 20, center = true, $fn = 30);
translate([-(130 / 2) + 8.25, -32, 8]) {
translate([-(130 / 2) + 8.25, -32, 8 - 13]) {
linear_bearing(padD = 0.2);
cylinder(r = 9 / 2, h = 40, center = true, $fn = 40);
}
}
difference () {
translate([10, -25, 4]) cube([110, 30, 5], center = true);
translate([2 + 22, -27, 1.5]) rotate([0, 0, 30]) m4BoltNut(bolt = 30, drop = false);
translate([2 - 22, -27, 1.5]) rotate([0, 0, 30]) m4BoltNut(bolt = 30, drop = false);
}
//translate([(130 / 2) + 8.25, RailsY, XOffset]) rotate([0, 0, 0]) linearMotionRod(RodLength);
//translate([(-130 / 2) + 8.25, RailsY, XOffset]) rotate([0, 0, 0]) linearMotionRod(RodLength);
}
module jkLensBrace () {
difference () {
union () {
translate([2, -20, -(75 / 2) + 1.5]) {
difference () {
cube([80, 20, 75], center = true);
difference () {
cube([60, 20 + 1, 55], center = true);
union () {
rotate([0, 45 ,0]) cube([200, 20 + 2, 15], center = true);
rotate([0, -45 ,0]) cube([200, 20 + 2, 15], center = true);
}
}
}
}
translate([2, -25, -75 + 4]) cube([90, 20, 5], center = true);
}
translate([2, -30, -(75 / 2) + 1 ]) cube([60, 20, 60], center = true);
//m5
translate([2 + 23, -25, -75 + 3.4]) rotate([0, 0, 30]) m5Nut();
translate([2 - 23, -25, -75 + 3.4]) rotate([0, 0, 30]) m5Nut();
translate([2 + 22, -27, 0]) cylinder(r = R(4.25), h = 30, center = true, $fn = 30);
translate([2 - 22, -27, 0]) cylinder(r = R(4.25), h = 30, center = true, $fn = 30);
}
}
module debug () {
@ -504,6 +550,8 @@ if (PART == "lens_assembly_camera_bellows_board") {
lensAssemblyThreadedCollar(6, 0.2);
} else if (PART == "lens_assembly_jk_mount") {
jkLensMount();
} else if (PART == "lens_assembly_jk_brace") {
rotate([-90, 0, 0]) jkLensBrace();
} else {
debug();
}

View File

@ -226,9 +226,9 @@ module rail_end (pos = [0, 0, 0], rot = [90, 0, 0], Motors = true, Projector = f
}
//BOM: 2,T8 Nut, N/A, For drive screw
//BOM: 2, T8 Nut, Tr8x2, For drive screw
//BOM: 2, Linear bearing, N/A, For center rails
//BOM: 8, Radial bearing, N/A, For something
//BOM: 8, 608-RS Ball Bearing, 608-RS, To smooth sled moving along rails
module sled (pos = [0, 0, 0], rot = [90, 0, 0], Length = 60) {
X = RailEndX;

View File

@ -323,6 +323,40 @@ module usb_protector () {
}
}
module power_cable () {
OD = 14;
difference () {
union () {
cylinder(r = R(18), h = 2, center = true, $fn = 80);
translate([0, 0, 10 / 2]) cylinder(r = R(OD), h = 10, center = true, $fn = 80);
}
cylinder(r = R(6.75), h = 40, center = true, $fn = 80);
translate([0, 0, 7.75]) difference() {
cylinder(r = R(OD + 2), h = 5, center = true);
cylinder(r = R(8), h = 5 + 1, center = true, $fn = 80);
translate([0, 0, -0.1]) cylinder(r2 = R(9), r1 = R(OD + .5), h = 5, center = true, $fn = 80);
}
}
}
module power_cable_halves () {
NotchSpacing = 10.5;
translate([-3, 0, 0]) difference () {
power_cable();
translate([50 / 2, 0, 0]) cube([50, 50, 50], center = true);
translate([0, NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true);
translate([0, -NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true);
}
translate([3, 0, 0]) difference () {
power_cable();
difference () {
translate([-50 / 2, 0, 0]) cube([50, 50, 50], center = true);
translate([0, NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true);
translate([0, -NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true);
}
}
}
module debug () {
case_debug();
translate([0, 0, -CaseInnerZ/2+(CaseMountsH)]) electronics_mount();
@ -332,14 +366,14 @@ module debug () {
translate(ArduinoPosition) translate([-27.5, -8, -10]) electronics_attachment();
}
PART="electronics_attachment";
PART="power_cable";
if (PART == "electronics_mount") {
electronics_mount();
} else if (PART == "electronics_attachment") {
electronics_attachment();
} else if (PART == "case_mounts") {
case_mounts();
} else if (PART == "power_cable") {
power_cable_halves();
} else if (PART == "usb_protector") {
usb_protector();
} else {

View File

@ -50,9 +50,30 @@ tac "${1}" | while read line; do
fi
done
echo "quantity,part_id,part,price" > "${TOTAL}"
echo "quantity,part,part_id,price" > "${TOTAL}"
sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${DESTINATION} bom" -cmd ".import ${PRICES} prices"\
'SELECT SUM(quantity),part,part_id, SUM(quantity) * (COALESCE((SELECT prices.price FROM prices WHERE prices.part = bom.part LIMIT 1), 0)) as price FROM bom GROUP BY part ORDER BY part DESC;' >> "${TOTAL}"
'SELECT SUM(quantity),part,part_id, CAST( CEIL( CAST(SUM(quantity) AS FLOAT) * (SELECT CAST(prices.price AS FLOAT) / CAST(prices.quantity AS FLOAT) FROM prices WHERE prices.part = bom.part LIMIT 1) ) AS INTEGER) as price FROM bom GROUP BY part ORDER BY part DESC;' >> "${TOTAL}"
sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${TOTAL} bom" -cmd ".import ${PRICES} prices" -cmd '.mode markdown' \
"SELECT part as Part, quantity as Qty, \
printf('$%.2f', CAST(price AS FLOAT) / 100) as 'Cost (USD)', \
printf( '[%s for $%.2f](%s)', (SELECT prices.quantity FROM prices WHERE prices.part = bom.part), (SELECT CAST(prices.price AS FLOAT) / 100 FROM prices WHERE prices.part = bom.part), (SELECT prices.url FROM prices WHERE prices.part = bom.part)) as 'Minumum' \
FROM bom ORDER BY part DESC;"
sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${TOTAL} bom" -cmd ".import ${PRICES} prices" -cmd '.mode markdown' \
"SELECT 'TOTAL', SUM(quantity) AS qty, \
printf('$%.2f', CAST(SUM(price) AS FLOAT) / 100) as total, \
printf('$%.2f', ( SELECT CAST( SUM(price) AS FLOAT) / 100 FROM prices WHERE prices.part IN ( SELECT bom.part FROM bom ) ) ) as min \
FROM bom;" | grep -v 'qty'
sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${TOTAL} bom"\
'SELECT SUM(quantity),"N/A","TOTALS", SUM(price) FROM bom;' | tr -d '"' >> "${TOTAL}"
"SELECT SUM(quantity), 'TOTAL', 'N/A', SUM(price) FROM bom;" | tr -d '"' >> "${TOTAL}"
NONEFOUND=$(sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${DESTINATION} bom" -cmd ".import ${PRICES} prices" -cmd '.mode column' -cmd '.headers off' \
'SELECT DISTINCT part FROM bom WHERE part NOT IN (SELECT part FROM prices) ORDER BY part;')
if [[ "${NONEFOUND}" != "" ]]; then
echo "No price found for the following parts:"
echo "${NONEFOUND}"
fi