In my application I have a requirement to duplicate a customers order. (They want to order again, so need to create a new OrderHeader record with all of the OrderLines duplicated and attached to the new record. Hope this makes sense. So my logic is:
The OrderHeader records are displayed in a query and when a row is selected, I store the selectedOrderHeader record in LoggedInRegularUser (LIRU). Then when the duplicate buttons is clicked my process does the following
1). FIND OrderHeader where OrderHeader = LIRU.selectedOrderHeader
2). CREATE OrderHeader with OrderHeader.attributeToDuplicate = OrderHeader.existingAttribute, .....
3). FIND OrderHeader WHERE OrderHeader.ob_Customers = LIRU.selectedCustomer ORDER BY OrderHeader.ID DESC TAKE BEST 1
4). FIND OrderLines where OrderLines.ob_OrderHeader = LIRU.selectedOrderHeader IN BATCHES OF 1
5). CREATE OrderLines WITH OrderLines.ob_OrderHeader = OrderHeader, ....
So, this 1) Finds the orderHeader to duplicate, 2) creates new OrderHeader Record, 3) Finds this record so I can use it to relate the children records (This does not look like very efficient code, esp. with large tables), 4) Find all of the OrderLines from the original order, and finally creating new OrderLines, one by one.
Is there a better, more efficient way?
Thanks
Bruce
Duplicating a Parent with multiple children. Best way?
Re: Duplicating a Parent with multiple children. Best way?
I had to do similar thing but more complex and more levels of hierarchy. And my case isn't just for one order, it's for a batch of orders, which basically ends up to be loop within loop within loop. And in each loop a bunch of processes takes places. Because of that, each loop requires BATCHES OF 1 to work correctly. But it also slows it down hugely.
-
- Posts: 619
- Joined: Wed Jun 17, 2015 11:16 pm
- Location: Omaha, Nebraska
- Contact:
Re: Duplicating a Parent with multiple children. Best way?
I see a couple potentials ways to trim this down. The simplest being:
1. FIND OrderHeader where OrderHeader = LIRU.selectedOrderHeader
2. DUPLICATE OrderHeader
3. DUPLICATE thisOrderHeader.OrderLines TO thatOrderHeader.OrderLines
Note: Step 3 assumes that after the DUPLICATE in step #2, you are able to reference the newly created OrderHeader using thatOrderHeader. I haven't tried it. If it doesn't ... I know it will work using CREATE like you already had.
1. FIND OrderHeader where OrderHeader = LIRU.selectedOrderHeader
2. DUPLICATE OrderHeader
3. DUPLICATE thisOrderHeader.OrderLines TO thatOrderHeader.OrderLines
Note: Step 3 assumes that after the DUPLICATE in step #2, you are able to reference the newly created OrderHeader using thatOrderHeader. I haven't tried it. If it doesn't ... I know it will work using CREATE like you already had.
VocalDay Solutions - Agility - Predictability - Quality
We specialize in enabling business through the innovative use of technology.
AwareIM app with beautiful UI/UX - https://screencast-o-matic.com/watch/crfUrrVeB3t
We specialize in enabling business through the innovative use of technology.
AwareIM app with beautiful UI/UX - https://screencast-o-matic.com/watch/crfUrrVeB3t
-
- Posts: 2418
- Joined: Mon Jul 02, 2012 12:24 am
- Location: Ulaanbaatar, Mongolia
Re: Duplicating a Parent with multiple children. Best way?
I am sure there are other ways but this is how I would try it....
Process 1 (Takes Purchase Order to Duplicate as Parameter
CREATE OrderHeader with OrderHeader.attribute1=ThisOrderHeader.Attribute1, OrderHeader.attribute2=ThisOrderHeader.Attribute2,OrderHeader.attribute3=ThisOrderHeader.Attribute3..etc
DoOrderLinesProcess
Process 2 - DoOrderLinesProcess - (OrderHeader is taken as Parameter - Both will be visible - First one is This and Created one is That)
FIND OrderLines WHERE OrderLine.ob_OrderHeader=ThisOrderHeader IN BATCHES OF 1
CREATE OrderLines WITH OrderLines.ob_OrderHeader=ThatOrderHeader, OrderLines.Attribute1=ThisOrderLines.Attribute1,OrderLines.Attribute2=ThisOrderLines.Attribute2,OrderLines.Attribute3=ThisOrderLines.Attribute3,etc etc
You could also do it with DUPLICATE which it more efficient and elegant if you do it correctly.
DUPLICATE ThisOrderHeader.om_OrderLines WITH .... etc etc
Process 1 (Takes Purchase Order to Duplicate as Parameter
CREATE OrderHeader with OrderHeader.attribute1=ThisOrderHeader.Attribute1, OrderHeader.attribute2=ThisOrderHeader.Attribute2,OrderHeader.attribute3=ThisOrderHeader.Attribute3..etc
DoOrderLinesProcess
Process 2 - DoOrderLinesProcess - (OrderHeader is taken as Parameter - Both will be visible - First one is This and Created one is That)
FIND OrderLines WHERE OrderLine.ob_OrderHeader=ThisOrderHeader IN BATCHES OF 1
CREATE OrderLines WITH OrderLines.ob_OrderHeader=ThatOrderHeader, OrderLines.Attribute1=ThisOrderLines.Attribute1,OrderLines.Attribute2=ThisOrderLines.Attribute2,OrderLines.Attribute3=ThisOrderLines.Attribute3,etc etc
You could also do it with DUPLICATE which it more efficient and elegant if you do it correctly.
DUPLICATE ThisOrderHeader.om_OrderLines WITH .... etc etc
Cheers,
Mark
_________________
AwareIM 6.0, 8.7, 8.8, 9.0 , MariaDB, Windows 10, Ubuntu Linux. Theme: Default, Browser: Arc
Upcloud, Obsidian....
Mark
_________________
AwareIM 6.0, 8.7, 8.8, 9.0 , MariaDB, Windows 10, Ubuntu Linux. Theme: Default, Browser: Arc
Upcloud, Obsidian....
Re: Duplicating a Parent with multiple children. Best way?
Tom - V8.8 build 3137 - MySql / PostGres
Re: Duplicating a Parent with multiple children. Best way?
John, your solution is both elegant (short is good) and it works!
Thanks. I still have to get my head around THIS and THAT....
(of course, could have done it easy peasy using as stored procedure, but do want to embrace the Aware way of doing things.)
Bruce
Thanks. I still have to get my head around THIS and THAT....
(of course, could have done it easy peasy using as stored procedure, but do want to embrace the Aware way of doing things.)
Bruce
-
- Posts: 619
- Joined: Wed Jun 17, 2015 11:16 pm
- Location: Omaha, Nebraska
- Contact:
Re: Duplicating a Parent with multiple children. Best way?
Glad it worked.
For situations where you can't do exact duplicates, you probably need to use CREATE. In any case, I would avoid using BATCHES of 1. As I understand it ... AwareIM will will force a separate transaction to start for each read and insert which # 1 goes against the purpose of transactions and #2 is crazy inefficient.
For situations where you can't do exact duplicates, you probably need to use CREATE. In any case, I would avoid using BATCHES of 1. As I understand it ... AwareIM will will force a separate transaction to start for each read and insert which # 1 goes against the purpose of transactions and #2 is crazy inefficient.
VocalDay Solutions - Agility - Predictability - Quality
We specialize in enabling business through the innovative use of technology.
AwareIM app with beautiful UI/UX - https://screencast-o-matic.com/watch/crfUrrVeB3t
We specialize in enabling business through the innovative use of technology.
AwareIM app with beautiful UI/UX - https://screencast-o-matic.com/watch/crfUrrVeB3t
Re: Duplicating a Parent with multiple children. Best way?
Thanks for the response. re: batches of 1, On that vein, I have a question about Processes, when you need to have a 2nd line
If I put the following in one line
FIND BO.......
BO.attr = ......
and there are multiple rows returned, I don't get the results I expect
However, if my process has 2 lines, 1st does the find, the 2nd does the update, it seems like it will not start the 2nd line until the 1st one completes.
Is that the only diff. between having one or multiple lines ? (besides the obvious conditional switches?
Thanks
Bruce
If I put the following in one line
FIND BO.......
BO.attr = ......
and there are multiple rows returned, I don't get the results I expect
However, if my process has 2 lines, 1st does the find, the 2nd does the update, it seems like it will not start the 2nd line until the 1st one completes.
Is that the only diff. between having one or multiple lines ? (besides the obvious conditional switches?
Thanks
Bruce
-
- Posts: 619
- Joined: Wed Jun 17, 2015 11:16 pm
- Location: Omaha, Nebraska
- Contact:
Re: Duplicating a Parent with multiple children. Best way?
I'm not 100% certain that I understand the question, but I'll take a stab ...
If you are trying to simulate a For Each loop ... i.e. for each record found by the FIND, do something ... it seems like using BATCHES OF 1 is the approach recommended in the forum because it does "work". But for the reasons mentioned above I don't want to use it. I even wonder if there is a bug, because having to use BATCHES OF 1 is not in alignment with the User Guide.
From page 73
*******
Rule 1: FIND Account WHERE Account.Balance < 100
Rule 2: Account.State = 'CLOSED'
The first rule runs a query that finds all accounts with balances less than 100. The second rule changes the state of found accounts.
********
But this doesn't work correctly ... so my impression is that USING BATCHES OF 1 has become the defacto answer because visually it works. But it loses the ability to have a single transaction wrap the operation i.e. treat it as a batch.
The way I've been able to get around it ... is to split the process into two processes.
[b]Process1[/b]
FIND BO Where ...
Process2
[b]Process2[/b]
Update BO ...
It's a pain to have to do this, but it does work and I believe (maybe I should say ... hope) that the combined processes are executed as a single transaction.
Maybe support can chime in on this?
If you are trying to simulate a For Each loop ... i.e. for each record found by the FIND, do something ... it seems like using BATCHES OF 1 is the approach recommended in the forum because it does "work". But for the reasons mentioned above I don't want to use it. I even wonder if there is a bug, because having to use BATCHES OF 1 is not in alignment with the User Guide.
From page 73
*******
Rule 1: FIND Account WHERE Account.Balance < 100
Rule 2: Account.State = 'CLOSED'
The first rule runs a query that finds all accounts with balances less than 100. The second rule changes the state of found accounts.
********
But this doesn't work correctly ... so my impression is that USING BATCHES OF 1 has become the defacto answer because visually it works. But it loses the ability to have a single transaction wrap the operation i.e. treat it as a batch.
The way I've been able to get around it ... is to split the process into two processes.
[b]Process1[/b]
FIND BO Where ...
Process2
[b]Process2[/b]
Update BO ...
It's a pain to have to do this, but it does work and I believe (maybe I should say ... hope) that the combined processes are executed as a single transaction.
Maybe support can chime in on this?
VocalDay Solutions - Agility - Predictability - Quality
We specialize in enabling business through the innovative use of technology.
AwareIM app with beautiful UI/UX - https://screencast-o-matic.com/watch/crfUrrVeB3t
We specialize in enabling business through the innovative use of technology.
AwareIM app with beautiful UI/UX - https://screencast-o-matic.com/watch/crfUrrVeB3t