ApiLogicServer 15.2.3__py3-none-any.whl → 15.2.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. api_logic_server_cli/api_logic_server.py +3 -1
  2. api_logic_server_cli/prototypes/base/.github/.copilot-instructions.md +114 -52
  3. api_logic_server_cli/prototypes/base/docs/training/testing.md +95 -9
  4. api_logic_server_cli/prototypes/base/test/api_logic_server_behave/behave_logic_report.py +19 -6
  5. api_logic_server_cli/prototypes/basic_demo/.github/.copilot-instructions.md +744 -0
  6. api_logic_server_cli/prototypes/basic_demo/customizations/logic/declare_logic.py +17 -1
  7. api_logic_server_cli/prototypes/basic_demo/readme.md +13 -5
  8. api_logic_server_cli/prototypes/basic_demo/tutor.md +1436 -0
  9. api_logic_server_cli/prototypes/manager/.github/.copilot-instructions.md +50 -23
  10. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/.github/.copilot-instructions.md +3 -0
  11. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/customizations/logic/declare_logic.py +17 -1
  12. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/docs/training/testing.md +95 -9
  13. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/iteration/logic/declare_logic.py +17 -1
  14. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/logic/declare_logic.py +38 -1
  15. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/features/order_processing.feature +59 -50
  16. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/features/steps/order_processing_steps.py +395 -248
  17. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/behave.log +66 -62
  18. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Carbon_Neutral_Discount_A.log +51 -41
  19. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Change_Order_Customer.log +29 -0
  20. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Change_Product_in_Item.log +35 -0
  21. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Delete_Item_Reduces_Order.log +39 -19
  22. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Exceed_Credit_Limit_Rejec.log +36 -45
  23. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Good_Order_Placed_via_B2B.log +50 -40
  24. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Item_Quantity_Change.log +33 -0
  25. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Multi-Item_Order_via_B2B_.log +67 -0
  26. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Ship_Order_Excludes_from_.log +24 -14
  27. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Transaction_Processing.log +26 -17
  28. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/logs/scenario_logic_logs/Unship_Order_Includes_in_.log +24 -14
  29. api_logic_server_cli/prototypes/manager/samples/basic_demo_sample/test/api_logic_server_behave/reports/Behave Logic Report.md +361 -146
  30. api_logic_server_cli/prototypes/manager/system/ApiLogicServer-Internal-Dev/copilot-dev-context.md +270 -2
  31. {apilogicserver-15.2.3.dist-info → apilogicserver-15.2.10.dist-info}/METADATA +25 -16
  32. {apilogicserver-15.2.3.dist-info → apilogicserver-15.2.10.dist-info}/RECORD +36 -30
  33. {apilogicserver-15.2.3.dist-info → apilogicserver-15.2.10.dist-info}/WHEEL +0 -0
  34. {apilogicserver-15.2.3.dist-info → apilogicserver-15.2.10.dist-info}/entry_points.txt +0 -0
  35. {apilogicserver-15.2.3.dist-info → apilogicserver-15.2.10.dist-info}/licenses/LICENSE +0 -0
  36. {apilogicserver-15.2.3.dist-info → apilogicserver-15.2.10.dist-info}/top_level.txt +0 -0
@@ -1,19 +1,36 @@
1
- This report shows test results with embedded logic execution traces.
1
+ ## Basic Demo Sample
2
2
 
3
- **For complete documentation on using Behave:** See [Behave.md](https://apilogicserver.github.io/Docs/Behave/)
3
+ This is a basic demonstration project created from a simple natural language prompt using API Logic Server's GenAI capabilities.
4
4
 
5
- **About This Project:**
5
+ ### Data Model
6
6
 
7
- _**TODO:** [Describe your project here - what it does, key features tested, etc.]_
7
+ ![Basic Demo Data Model](https://apilogicserver.github.io/Docs/images/basic_demo/basic_demo_data_model.jpeg)
8
8
 
9
-  
9
+ ### Creation Prompt
10
+
11
+ This project was created from the following natural language prompt:
12
+
13
+ ```
14
+ Create a system with customers, orders, items and products.
15
+
16
+ Include a notes field for orders.
10
17
 
11
- This report combines:
18
+ Use case: Check Credit
19
+ 1. The Customer's balance is less than the credit limit
20
+ 2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
21
+ 3. The Order's amount_total is the sum of the Item amount
22
+ 4. The Item amount is the quantity * unit_price
23
+ 5. The Item unit_price is copied from the Product unit_price
12
24
 
13
- * Behave log (lists Features, test Scenarios, results), with embedded
14
- * Logic showing rules executed, and how they operated
25
+ Use case: App Integration
26
+ 1. Send the Order to Kafka topic 'order_shipping' if the date_shipped is not None.
27
+ ```
28
+
29
+ The sample Scenarios below were chosen to illustrate the basic patterns of using rules. Open the disclosure box ("Tests - and their logic...") to see the implementation and notes.
15
30
 
16
- ---
31
+ The following report was created during test suite execution.
32
+
33
+  
17
34
 
18
35
  # Behave Logic Report
19
36
   
@@ -22,12 +39,51 @@ This report combines:
22
39
 
23
40
   
24
41
   
25
- ### Scenario: Transaction Processing # features/about.feature:8
26
-
42
+ ### Scenario: Transaction Processing
27
43
    Scenario: Transaction Processing
28
-    **Given** Sample Database
29
-    **When** Transactions are submitted
30
-    **Then** Enforce business policies with Logic (rules + code)
44
+    Given Sample Database
45
+    When Transactions are submitted
46
+    Then Enforce business policies with Logic (rules + code)
47
+ <details markdown>
48
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
49
+
50
+
51
+ &nbsp;
52
+ &nbsp;
53
+
54
+
55
+ **Rules Used** in Scenario: Transaction Processing
56
+ ```
57
+ ```
58
+ **Logic Log** in Scenario: Transaction Processing
59
+ ```
60
+
61
+ The following rules have been activate
62
+ - 2025-10-24 08:44:43,762 - logic_logger - DEBU
63
+ Rule Bank[0x10927aba0] (loaded 2025-10-22 20:22:19.960861
64
+ Mapped Class[Customer] rules
65
+ Constraint Function: None
66
+ Constraint Function: None
67
+ Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>
68
+ Mapped Class[SysEmail] rules
69
+ RowEvent SysEmail.send_mail()
70
+ Mapped Class[Order] rules
71
+ Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None
72
+ RowEvent Order.send_order_to_shipping()
73
+ Mapped Class[Item] rules
74
+ Derive <class 'database.models.Item'>.amount as Formula (1): <function
75
+ Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price
76
+ Logic Bank - 13 rules loaded - 2025-10-24 08:44:43,771 - logic_logger - INF
77
+ Logic Bank - 13 rules loaded - 2025-10-24 08:44:43,771 - logic_logger - INF
78
+
79
+ Logic Phase: ROW LOGIC (session=0x10a3778a0) (sqlalchemy before_flush) - 2025-10-24 08:44:43,794 - logic_logger - INF
80
+ ..Customer[None] {Insert - client} id: None, name: Alice 1761320683776, balance: 0, credit_limit: 5000, email: None, email_opt_out: None row: 0x10a56d050 session: 0x10a3778a0 ins_upd_dlt: ins, initial: ins - 2025-10-24 08:44:43,796 - logic_logger - INF
81
+ ..Customer[None] {server aggregate_defaults: balance } id: None, name: Alice 1761320683776, balance: 0, credit_limit: 5000, email: None, email_opt_out: None row: 0x10a56d050 session: 0x10a3778a0 ins_upd_dlt: ins, initial: ins - 2025-10-24 08:44:43,796 - logic_logger - INF
82
+ Logic Phase: COMMIT LOGIC (session=0x10a3778a0) - 2025-10-24 08:44:43,796 - logic_logger - INF
83
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a3778a0) - 2025-10-24 08:44:43,803 - logic_logger - INF
84
+
85
+ ```
86
+ </details>
31
87
 
32
88
  &nbsp;
33
89
  &nbsp;
@@ -35,37 +91,55 @@ This report combines:
35
91
 
36
92
  &nbsp;
37
93
  &nbsp;
38
- ### Scenario: Good Order Placed # features/order_processing.feature:3
94
+ ### Scenario: Good Order Placed via B2B API
95
+ &emsp; Scenario: Good Order Placed via B2B API
96
+ &emsp;&emsp; Given Customer "Alice" with balance 0 and credit limit 5000
97
+ &emsp;&emsp; When B2B order placed for "Alice" with 5 Widget
98
+ &emsp;&emsp; Then Customer balance should be 450
99
+ And Order amount_total should be 450
100
+ And Item amount should be 450
101
+ And Item unit_price should be 90
102
+ <details markdown>
103
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
104
+
39
105
 
40
- &emsp; Scenario: Good Order Placed
41
- &emsp;&emsp; **Given** Customer "Alice" with balance 0 and credit limit 1000
42
- &emsp;&emsp; **When** B2B order placed for "Alice" with 5 Widget
43
- &emsp;&emsp; **Then** Customer "Alice" balance should be 450
44
- &emsp;&emsp; **And** Order amount_total should be 450
45
- &emsp;&emsp; **And** Item amount should be 450
46
-
47
106
  &nbsp;
48
107
  &nbsp;
49
- ### Scenario: Increase Item Quantity # features/order_processing.feature:10
50
108
 
51
- &emsp; Scenario: Increase Item Quantity
52
- &emsp;&emsp; **Given** Customer "Bob" with balance 0 and credit limit 2000
53
- &emsp;&emsp; **And** Order exists for "Bob" with 5 Widget
54
- &emsp;&emsp; **When** Item quantity changed to 10
55
- &emsp;&emsp; **Then** Item amount should be 900
56
- &emsp;&emsp; **And** Order amount_total should be 900
57
- &emsp;&emsp; **And** Customer "Bob" balance should be 900
109
+
110
+ **Rules Used** in Scenario: Good Order Placed via B2B API
111
+ ```
112
+ Customer
113
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
114
+ Item
115
+ 2. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
116
+ 3. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
117
+ Order
118
+ 4. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
119
+ 5. RowEvent Order.send_order_to_shipping()
120
+ ```
121
+ **Logic Log** in Scenario: Good Order Placed via B2B API
122
+ ```
123
+
124
+ Good Order Placed via B2B AP
125
+ - 2025-10-24 08:44:43,812 - logic_logger - INF
126
+
127
+ Logic Phase: ROW LOGIC (session=0x10a377ac0) (sqlalchemy before_flush) - 2025-10-24 08:44:43,816 - logic_logger - INF
128
+ ..Customer[28] {Update - client} id: 28, name: Alice 1761320683776, balance: 0E-10, credit_limit: 5000.0000000000, email: None, email_opt_out: None row: 0x10a56d4d0 session: 0x10a377ac0 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,817 - logic_logger - INF
129
+ Logic Phase: COMMIT LOGIC (session=0x10a377ac0) - 2025-10-24 08:44:43,817 - logic_logger - INF
130
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a377ac0) - 2025-10-24 08:44:43,817 - logic_logger - INF
131
+
132
+ ```
133
+ </details>
58
134
 
59
135
  &nbsp;
60
136
  &nbsp;
61
- ### Scenario: Carbon Neutral Discount Applied # features/order_processing.feature:18
62
-
63
- &emsp; Scenario: Carbon Neutral Discount Applied
64
- &emsp;&emsp; **Given** Customer "Carol" with balance 0 and credit limit 2000
65
- &emsp;&emsp; **When** B2B order placed for "Carol" with 10 carbon neutral Green
66
- &emsp;&emsp; **Then** Item amount should be 981
67
- &emsp;&emsp; **And** Order amount_total should be 981
68
- &emsp;&emsp; **And** Customer "Carol" balance should be 981
137
+ ### Scenario: Multi-Item Order via B2B API
138
+ &emsp; Scenario: Multi-Item Order via B2B API
139
+ &emsp;&emsp; Given Customer "Bob" with balance 0 and credit limit 3000
140
+ &emsp;&emsp; When B2B order placed for "Bob" with 3 Widget and 2 Gadget
141
+ &emsp;&emsp; Then Customer balance should be 570
142
+ And Order amount_total should be 570
69
143
  <details markdown>
70
144
  <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
71
145
 
@@ -74,53 +148,82 @@ This report combines:
74
148
  &nbsp;
75
149
 
76
150
 
77
- **Rules Used** in Scenario: Carbon Neutral Discount Applied # features/order_processing.feature:18
151
+ **Rules Used** in Scenario: Multi-Item Order via B2B API
78
152
  ```
79
153
  Customer
80
- 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x10c5f8cc0>)
154
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
81
155
  Item
82
- 2. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
83
- 3. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
156
+ 2. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
157
+ 3. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
84
158
  Order
85
159
  4. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
86
160
  5. RowEvent Order.send_order_to_shipping()
87
161
  ```
88
- **Logic Log** in Scenario: Carbon Neutral Discount Applied # features/order_processing.feature:18
162
+ **Logic Log** in Scenario: Multi-Item Order via B2B API
89
163
  ```
90
164
 
91
- Carbon Neutral Discount Applie
92
- - 2025-10-20 19:17:14,919 - logic_logger - INF
165
+ Multi-Item Order via B2B AP
166
+ - 2025-10-24 08:44:43,839 - logic_logger - INF
93
167
 
94
- Logic Phase: ROW LOGIC (session=0x10d61bbd0) (sqlalchemy before_flush) - 2025-10-20 19:17:14,921 - logic_logger - INF
95
- ..Customer[43] {Update - client} id: 43, name: Carol 1761013034915, balance: 0E-10, credit_limit: 2000.0000000000, email: None, email_opt_out: None row: 0x10d6e4250 session: 0x10d61bbd0 ins_upd_dlt: upd, initial: upd - 2025-10-20 19:17:14,921 - logic_logger - INF
96
- Logic Phase: COMMIT LOGIC (session=0x10d61bbd0) - 2025-10-20 19:17:14,921 - logic_logger - INF
97
- Logic Phase: AFTER_FLUSH LOGIC (session=0x10d61bbd0) - 2025-10-20 19:17:14,921 - logic_logger - INF
168
+ Logic Phase: ROW LOGIC (session=0x10a574e20) (sqlalchemy before_flush) - 2025-10-24 08:44:43,841 - logic_logger - INF
169
+ ..Customer[29] {Update - client} id: 29, name: Bob 1761320683835, balance: 0E-10, credit_limit: 3000.0000000000, email: None, email_opt_out: None row: 0x10a56c850 session: 0x10a574e20 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,841 - logic_logger - INF
170
+ Logic Phase: COMMIT LOGIC (session=0x10a574e20) - 2025-10-24 08:44:43,841 - logic_logger - INF
171
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a574e20) - 2025-10-24 08:44:43,842 - logic_logger - INF
98
172
 
99
173
  ```
100
174
  </details>
101
175
 
102
176
  &nbsp;
103
177
  &nbsp;
104
- ### Scenario: Change Order Customer # features/order_processing.feature:25
178
+ ### Scenario: Carbon Neutral Discount Applied
179
+ &emsp; Scenario: Carbon Neutral Discount Applied
180
+ &emsp;&emsp; Given Customer "Diana" with balance 0 and credit limit 5000
181
+ &emsp;&emsp; When B2B order placed for "Diana" with 10 carbon neutral Gadget
182
+ &emsp;&emsp; Then Customer balance should be 1350
183
+ And Item amount should be 1350
184
+ <details markdown>
185
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
186
+
105
187
 
106
- &emsp; Scenario: Change Order Customer
107
- &emsp;&emsp; **Given** Customer "Dave" with balance 0 and credit limit 1500
108
- &emsp;&emsp; **And** Customer "Eve" with balance 0 and credit limit 1500
109
- &emsp;&emsp; **And** Order exists for "Dave" with 5 Widget
110
- &emsp;&emsp; **When** Order customer changed to "Eve"
111
- &emsp;&emsp; **Then** Customer "Dave" balance should be 0
112
- &emsp;&emsp; **And** Customer "Eve" balance should be 450
113
-
114
188
  &nbsp;
115
189
  &nbsp;
116
- ### Scenario: Delete Item Reduces Totals # features/order_processing.feature:33
117
190
 
118
- &emsp; Scenario: Delete Item Reduces Totals
119
- &emsp;&emsp; **Given** Customer "Frank" with balance 0 and credit limit 1500
120
- &emsp;&emsp; **And** Order exists for "Frank" with 3 Widget and 2 Gadget
121
- &emsp;&emsp; **When** First item deleted
122
- &emsp;&emsp; **Then** Order amount_total should be 300
123
- &emsp;&emsp; **And** Customer "Frank" balance should be 300
191
+
192
+ **Rules Used** in Scenario: Carbon Neutral Discount Applied
193
+ ```
194
+ Customer
195
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
196
+ Item
197
+ 2. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
198
+ 3. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
199
+ Order
200
+ 4. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
201
+ 5. RowEvent Order.send_order_to_shipping()
202
+ ```
203
+ **Logic Log** in Scenario: Carbon Neutral Discount Applied
204
+ ```
205
+
206
+ Carbon Neutral Discount Applie
207
+ - 2025-10-24 08:44:43,859 - logic_logger - INF
208
+
209
+ Logic Phase: ROW LOGIC (session=0x10a377240) (sqlalchemy before_flush) - 2025-10-24 08:44:43,861 - logic_logger - INF
210
+ ..Customer[30] {Update - client} id: 30, name: Diana 1761320683854, balance: 0E-10, credit_limit: 5000.0000000000, email: None, email_opt_out: None row: 0x10a44ba50 session: 0x10a377240 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,861 - logic_logger - INF
211
+ Logic Phase: COMMIT LOGIC (session=0x10a377240) - 2025-10-24 08:44:43,861 - logic_logger - INF
212
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a377240) - 2025-10-24 08:44:43,861 - logic_logger - INF
213
+
214
+ ```
215
+ </details>
216
+
217
+ &nbsp;
218
+ &nbsp;
219
+ ### Scenario: Item Quantity Change
220
+ &emsp; Scenario: Item Quantity Change
221
+ &emsp;&emsp; Given Customer "Charlie" with balance 0 and credit limit 2000
222
+ And Order is created for "Charlie" with 5 Widget
223
+ &emsp;&emsp; When Item quantity changed to 10
224
+ &emsp;&emsp; Then Item amount should be 900
225
+ And Order amount_total should be 900
226
+ And Customer balance should be 900
124
227
  <details markdown>
125
228
  <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
126
229
 
@@ -129,40 +232,45 @@ Logic Phase: AFTER_FLUSH LOGIC (session=0x10d61bbd0) - 2025-10-20
129
232
  &nbsp;
130
233
 
131
234
 
132
- **Rules Used** in Scenario: Delete Item Reduces Totals # features/order_processing.feature:33
235
+ **Rules Used** in Scenario: Item Quantity Change
133
236
  ```
134
237
  Customer
135
- 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x10c5f8cc0>)
238
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
136
239
  Item
137
240
  2. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
138
- 3. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
139
241
  Order
242
+ 3. RowEvent Order.send_order_to_shipping()
140
243
  4. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
141
- 5. RowEvent Order.send_order_to_shipping()
142
244
  ```
143
- **Logic Log** in Scenario: Delete Item Reduces Totals # features/order_processing.feature:33
245
+ **Logic Log** in Scenario: Item Quantity Change
144
246
  ```
145
247
 
146
- Delete Item Reduces Total
147
- - 2025-10-20 19:17:14,965 - logic_logger - INF
248
+ Item Quantity Chang
249
+ - 2025-10-24 08:44:43,889 - logic_logger - INF
148
250
 
149
- Logic Phase: ROW LOGIC (session=0x10d618af0) (sqlalchemy before_flush) - 2025-10-20 19:17:14,967 - logic_logger - INF
150
- ..Customer[46] {Update - client} id: 46, name: Frank 1761013034961, balance: 0E-10, credit_limit: 1500.0000000000, email: None, email_opt_out: None row: 0x10d8836d0 session: 0x10d618af0 ins_upd_dlt: upd, initial: upd - 2025-10-20 19:17:14,967 - logic_logger - INF
151
- Logic Phase: COMMIT LOGIC (session=0x10d618af0) - 2025-10-20 19:17:14,967 - logic_logger - INF
152
- Logic Phase: AFTER_FLUSH LOGIC (session=0x10d618af0) - 2025-10-20 19:17:14,967 - logic_logger - INF
251
+ Logic Phase: ROW LOGIC (session=0x10a376470) (sqlalchemy before_flush) - 2025-10-24 08:44:43,891 - logic_logger - INF
252
+ ..Item[32] {Update - client} id: 32, order_id: 27, product_id: 2, quantity: [5-->] 10, amount: 450.0000000000, unit_price: 90.0000000000 row: 0x10a56e150 session: 0x10a376470 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,891 - logic_logger - INF
253
+ ..Item[32] {Formula amount} id: 32, order_id: 27, product_id: 2, quantity: [5-->] 10, amount: [450.0000000000-->] 900.0000000000, unit_price: 90.0000000000 row: 0x10a56e150 session: 0x10a376470 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,891 - logic_logger - INF
254
+ ....Order[27] {Update - Adjusting order: amount_total} id: 27, notes: Test order - Item Quantity Change, customer_id: 31, CreatedOn: 2025-10-24, date_shipped: None, amount_total: [450.0000000000-->] 900.0000000000 row: 0x10a56ded0 session: 0x10a376470 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,891 - logic_logger - INF
255
+ ......Customer[31] {Update - Adjusting customer: balance} id: 31, name: Charlie 1761320683872, balance: [450.0000000000-->] 900.0000000000, credit_limit: 2000.0000000000, email: None, email_opt_out: None row: 0x10a56ed50 session: 0x10a376470 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,892 - logic_logger - INF
256
+ Logic Phase: COMMIT LOGIC (session=0x10a376470) - 2025-10-24 08:44:43,892 - logic_logger - INF
257
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a376470) - 2025-10-24 08:44:43,892 - logic_logger - INF
258
+ ....Order[27] {AfterFlush Event} id: 27, notes: Test order - Item Quantity Change, customer_id: 31, CreatedOn: 2025-10-24, date_shipped: None, amount_total: [450.0000000000-->] 900.0000000000 row: 0x10a56ded0 session: 0x10a376470 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,892 - logic_logger - INF
153
259
 
154
260
  ```
155
261
  </details>
156
262
 
157
263
  &nbsp;
158
264
  &nbsp;
159
- ### Scenario: Ship Order Excludes from Balance # features/order_processing.feature:40
160
-
161
- &emsp; Scenario: Ship Order Excludes from Balance
162
- &emsp;&emsp; **Given** Customer "Grace" with balance 0 and credit limit 1000
163
- &emsp;&emsp; **And** Order exists for "Grace" with 5 Widget
164
- &emsp;&emsp; **When** Order shipped
165
- &emsp;&emsp; **Then** Customer "Grace" balance should be 0
265
+ ### Scenario: Change Product in Item
266
+ &emsp; Scenario: Change Product in Item
267
+ &emsp;&emsp; Given Customer "Alice" with balance 0 and credit limit 5000
268
+ And Order is created for "Alice" with 5 Widget
269
+ &emsp;&emsp; When Item product changed to "Gadget"
270
+ &emsp;&emsp; Then Item unit_price should be 150
271
+ And Item amount should be 750
272
+ And Order amount_total should be 750
273
+ And Customer balance should be 750
166
274
  <details markdown>
167
275
  <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
168
276
 
@@ -171,40 +279,45 @@ Logic Phase: AFTER_FLUSH LOGIC (session=0x10d618af0) - 2025-10-20
171
279
  &nbsp;
172
280
 
173
281
 
174
- **Rules Used** in Scenario: Ship Order Excludes from Balance # features/order_processing.feature:40
282
+ **Rules Used** in Scenario: Change Product in Item
175
283
  ```
176
284
  Customer
177
- 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x10c5f8cc0>)
285
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
178
286
  Item
179
- 2. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
180
- 3. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
287
+ 2. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
288
+ 3. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
181
289
  Order
182
290
  4. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
183
291
  5. RowEvent Order.send_order_to_shipping()
184
292
  ```
185
- **Logic Log** in Scenario: Ship Order Excludes from Balance # features/order_processing.feature:40
293
+ **Logic Log** in Scenario: Change Product in Item
186
294
  ```
187
295
 
188
- Ship Order Excludes from Balanc
189
- - 2025-10-20 19:17:14,989 - logic_logger - INF
296
+ Change Product in Ite
297
+ - 2025-10-24 08:44:43,917 - logic_logger - INF
190
298
 
191
- Logic Phase: ROW LOGIC (session=0x10d618e20) (sqlalchemy before_flush) - 2025-10-20 19:17:14,991 - logic_logger - INF
192
- ..Customer[47] {Update - client} id: 47, name: Grace 1761013034985, balance: 0E-10, credit_limit: 1000.0000000000, email: None, email_opt_out: None row: 0x10d6e4ed0 session: 0x10d618e20 ins_upd_dlt: upd, initial: upd - 2025-10-20 19:17:14,991 - logic_logger - INF
193
- Logic Phase: COMMIT LOGIC (session=0x10d618e20) - 2025-10-20 19:17:14,991 - logic_logger - INF
194
- Logic Phase: AFTER_FLUSH LOGIC (session=0x10d618e20) - 2025-10-20 19:17:14,991 - logic_logger - INF
299
+ Logic Phase: ROW LOGIC (session=0x10a376140) (sqlalchemy before_flush) - 2025-10-24 08:44:43,920 - logic_logger - INF
300
+ ..Item[33] {Update - client} id: 33, order_id: 28, product_id: [2-->] 1, quantity: 5, amount: 450.0000000000, unit_price: 90.0000000000 row: 0x10a44a4d0 session: 0x10a376140 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,921 - logic_logger - INF
301
+ ..Item[33] {copy_rules for role: product - unit_price} id: 33, order_id: 28, product_id: [2-->] 1, quantity: 5, amount: 450.0000000000, unit_price: [90.0000000000-->] 150.0000000000 row: 0x10a44a4d0 session: 0x10a376140 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,921 - logic_logger - INF
302
+ ..Item[33] {Formula amount} id: 33, order_id: 28, product_id: [2-->] 1, quantity: 5, amount: [450.0000000000-->] 750.0000000000, unit_price: [90.0000000000-->] 150.0000000000 row: 0x10a44a4d0 session: 0x10a376140 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,921 - logic_logger - INF
303
+ ....Order[28] {Update - Adjusting order: amount_total} id: 28, notes: Test order - Change Product in Item, customer_id: 32, CreatedOn: 2025-10-24, date_shipped: None, amount_total: [450.0000000000-->] 750.0000000000 row: 0x10a44bb50 session: 0x10a376140 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,921 - logic_logger - INF
304
+ ......Customer[32] {Update - Adjusting customer: balance} id: 32, name: Alice 1761320683899, balance: [450.0000000000-->] 750.0000000000, credit_limit: 5000.0000000000, email: None, email_opt_out: None row: 0x10a44be50 session: 0x10a376140 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,921 - logic_logger - INF
305
+ Logic Phase: COMMIT LOGIC (session=0x10a376140) - 2025-10-24 08:44:43,922 - logic_logger - INF
306
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a376140) - 2025-10-24 08:44:43,922 - logic_logger - INF
307
+ ....Order[28] {AfterFlush Event} id: 28, notes: Test order - Change Product in Item, customer_id: 32, CreatedOn: 2025-10-24, date_shipped: None, amount_total: [450.0000000000-->] 750.0000000000 row: 0x10a44bb50 session: 0x10a376140 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,922 - logic_logger - INF
195
308
 
196
309
  ```
197
310
  </details>
198
311
 
199
312
  &nbsp;
200
313
  &nbsp;
201
- ### Scenario: Unship Order Includes in Balance # features/order_processing.feature:46
202
-
203
- &emsp; Scenario: Unship Order Includes in Balance
204
- &emsp;&emsp; **Given** Customer "Henry" with balance 0 and credit limit 1000
205
- &emsp;&emsp; **And** Shipped order exists for "Henry" with 5 Widget
206
- &emsp;&emsp; **When** Order unshipped
207
- &emsp;&emsp; **Then** Customer "Henry" balance should be 450
314
+ ### Scenario: Delete Item Reduces Order
315
+ &emsp; Scenario: Delete Item Reduces Order
316
+ &emsp;&emsp; Given Customer "Bob" with balance 0 and credit limit 3000
317
+ And Order is created for "Bob" with 3 Widget and 2 Gadget
318
+ &emsp;&emsp; When First item is deleted
319
+ &emsp;&emsp; Then Order amount_total should be 300
320
+ And Customer balance should be 300
208
321
  <details markdown>
209
322
  <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
210
323
 
@@ -213,49 +326,122 @@ Logic Phase: AFTER_FLUSH LOGIC (session=0x10d618e20) - 2025-10-20
213
326
  &nbsp;
214
327
 
215
328
 
216
- **Rules Used** in Scenario: Unship Order Includes in Balance # features/order_processing.feature:46
329
+ **Rules Used** in Scenario: Delete Item Reduces Order
217
330
  ```
218
331
  Customer
219
- 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x10c5f8cc0>)
332
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
220
333
  Order
221
334
  2. RowEvent Order.send_order_to_shipping()
335
+ 3. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
222
336
  ```
223
- **Logic Log** in Scenario: Unship Order Includes in Balance # features/order_processing.feature:46
337
+ **Logic Log** in Scenario: Delete Item Reduces Order
224
338
  ```
225
339
 
226
- Unship Order Includes in Balanc
227
- - 2025-10-20 19:17:15,013 - logic_logger - INF
340
+ Delete Item Reduces Orde
341
+ - 2025-10-24 08:44:43,951 - logic_logger - INF
228
342
 
229
- Logic Phase: ROW LOGIC (session=0x10d61a7a0) (sqlalchemy before_flush) - 2025-10-20 19:17:15,015 - logic_logger - INF
230
- ..Customer[48] {Update - client} id: 48, name: Henry 1761013035008, balance: 0E-10, credit_limit: 1000.0000000000, email: None, email_opt_out: None row: 0x10d8a12d0 session: 0x10d61a7a0 ins_upd_dlt: upd, initial: upd - 2025-10-20 19:17:15,015 - logic_logger - INF
231
- Logic Phase: COMMIT LOGIC (session=0x10d61a7a0) - 2025-10-20 19:17:15,015 - logic_logger - INF
232
- Logic Phase: AFTER_FLUSH LOGIC (session=0x10d61a7a0) - 2025-10-20 19:17:15,015 - logic_logger - INF
343
+ Logic Phase: ROW LOGIC (session=0x10a377df0) (sqlalchemy before_flush) - 2025-10-24 08:44:43,952 - logic_logger - INF
344
+ ..Item[34] {Delete - client} id: 34, order_id: 29, product_id: 2, quantity: 3, amount: 270.0000000000, unit_price: 90.0000000000 row: 0x10a448650 session: 0x10a377df0 ins_upd_dlt: dlt, initial: dlt - 2025-10-24 08:44:43,952 - logic_logger - INF
345
+ ....Order[29] {Update - Adjusting order: amount_total} id: 29, notes: Test order - Delete Item Reduces Order, customer_id: 33, CreatedOn: 2025-10-24, date_shipped: None, amount_total: [570.0000000000-->] 300.0000000000 row: 0x10a44b3d0 session: 0x10a377df0 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,952 - logic_logger - INF
346
+ ......Customer[33] {Update - Adjusting customer: balance} id: 33, name: Bob 1761320683930, balance: [570.0000000000-->] 300.0000000000, credit_limit: 3000.0000000000, email: None, email_opt_out: None row: 0x10a3cbcd0 session: 0x10a377df0 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,953 - logic_logger - INF
347
+ Logic Phase: COMMIT LOGIC (session=0x10a377df0) - 2025-10-24 08:44:43,953 - logic_logger - INF
348
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a377df0) - 2025-10-24 08:44:43,953 - logic_logger - INF
349
+ ....Order[29] {AfterFlush Event} id: 29, notes: Test order - Delete Item Reduces Order, customer_id: 33, CreatedOn: 2025-10-24, date_shipped: None, amount_total: [570.0000000000-->] 300.0000000000 row: 0x10a44b3d0 session: 0x10a377df0 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,953 - logic_logger - INF
233
350
 
234
351
  ```
235
352
  </details>
236
353
 
237
354
  &nbsp;
238
355
  &nbsp;
239
- ### Scenario: Exceed Credit Limit # features/order_processing.feature:52
356
+ ### Scenario: Change Order Customer
357
+ &emsp; Scenario: Change Order Customer
358
+ &emsp;&emsp; Given Customer "Alice" with balance 0 and credit limit 5000
359
+ And Customer "Bob" with balance 0 and credit limit 3000
360
+ And Order is created for "Alice" with 5 Widget
361
+ &emsp;&emsp; When Order customer changed to "Bob"
362
+ &emsp;&emsp; Then Customer "Alice" balance should be 0
363
+ And Customer "Bob" balance should be 450
364
+ <details markdown>
365
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
366
+
367
+
368
+ &nbsp;
369
+ &nbsp;
370
+
371
+
372
+ **Rules Used** in Scenario: Change Order Customer
373
+ ```
374
+ Customer
375
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
376
+ Order
377
+ 2. RowEvent Order.send_order_to_shipping()
378
+ ```
379
+ **Logic Log** in Scenario: Change Order Customer
380
+ ```
381
+
382
+ Change Order Custome
383
+ - 2025-10-24 08:44:43,976 - logic_logger - INF
240
384
 
241
- &emsp; Scenario: Exceed Credit Limit
242
- &emsp;&emsp; **Given** Customer "Ivan" with balance 0 and credit limit 100
243
- &emsp;&emsp; **When** B2B order placed for "Ivan" with 5 Widget
244
- &emsp;&emsp; **Then** Order creation should fail
245
- &emsp;&emsp; **And** Error message should contain "credit limit"
385
+ Logic Phase: ROW LOGIC (session=0x10a376f10) (sqlalchemy before_flush) - 2025-10-24 08:44:43,978 - logic_logger - INF
386
+ ..Order[30] {Update - client} id: 30, notes: Test order - Change Order Customer, customer_id: [34-->] 35, CreatedOn: 2025-10-24, date_shipped: None, amount_total: 450.0000000000 row: 0x10a4490d0 session: 0x10a376f10 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,978 - logic_logger - INF
387
+ ....Customer[35] {Update - Adjusting customer: balance, balance} id: 35, name: Bob 1761320683960, balance: [0E-10-->] 450.0000000000, credit_limit: 3000.0000000000, email: None, email_opt_out: None row: 0x10a44a7d0 session: 0x10a376f10 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,978 - logic_logger - INF
388
+ ....Customer[34] {Update - Adjusting Old customer} id: 34, name: Alice 1761320683958, balance: [450.0000000000-->] 0E-10, credit_limit: 5000.0000000000, email: None, email_opt_out: None row: 0x10a44bad0 session: 0x10a376f10 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,979 - logic_logger - INF
389
+ Logic Phase: COMMIT LOGIC (session=0x10a376f10) - 2025-10-24 08:44:43,979 - logic_logger - INF
390
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a376f10) - 2025-10-24 08:44:43,979 - logic_logger - INF
391
+ ..Order[30] {AfterFlush Event} id: 30, notes: Test order - Change Order Customer, customer_id: [34-->] 35, CreatedOn: 2025-10-24, date_shipped: None, amount_total: 450.0000000000 row: 0x10a4490d0 session: 0x10a376f10 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:43,979 - logic_logger - INF
392
+
393
+ ```
394
+ </details>
246
395
 
247
396
  &nbsp;
248
397
  &nbsp;
249
- ### Scenario: Change Product ID Re-copies Price # features/order_processing.feature:58
398
+ ### Scenario: Ship Order Excludes from Balance
399
+ &emsp; Scenario: Ship Order Excludes from Balance
400
+ &emsp;&emsp; Given Customer "Charlie" with balance 0 and credit limit 2000
401
+ And Order is created for "Charlie" with 2 Widget
402
+ &emsp;&emsp; When Order is shipped
403
+ &emsp;&emsp; Then Customer balance should be 0
404
+ And Order amount_total should be 180
405
+ <details markdown>
406
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
407
+
250
408
 
251
- &emsp; Scenario: Change Product ID Re-copies Price
252
- &emsp;&emsp; **Given** Customer "Jane" with balance 0 and credit limit 2000
253
- &emsp;&emsp; **And** Order exists for "Jane" with 5 Widget
254
- &emsp;&emsp; **When** Item product changed to "Gadget"
255
- &emsp;&emsp; **Then** Item unit_price should be 150
256
- &emsp;&emsp; **And** Item amount should be 750
257
- &emsp;&emsp; **And** Order amount_total should be 750
258
- &emsp;&emsp; **And** Customer "Jane" balance should be 750
409
+ &nbsp;
410
+ &nbsp;
411
+
412
+
413
+ **Rules Used** in Scenario: Ship Order Excludes from Balance
414
+ ```
415
+ Customer
416
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
417
+ Order
418
+ 2. RowEvent Order.send_order_to_shipping()
419
+ ```
420
+ **Logic Log** in Scenario: Ship Order Excludes from Balance
421
+ ```
422
+
423
+ Ship Order Excludes from Balanc
424
+ - 2025-10-24 08:44:43,999 - logic_logger - INF
425
+
426
+ Logic Phase: ROW LOGIC (session=0x10a377ac0) (sqlalchemy before_flush) - 2025-10-24 08:44:44,001 - logic_logger - INF
427
+ ..Order[31] {Update - client} id: 31, notes: Test order - Ship Order Excludes from Balance, customer_id: 36, CreatedOn: 2025-10-24, date_shipped: [None-->] 2025-10-22 00:00:00, amount_total: 180.0000000000 row: 0x10a44ac50 session: 0x10a377ac0 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:44,001 - logic_logger - INF
428
+ ....Customer[36] {Update - Adjusting customer: balance} id: 36, name: Charlie 1761320683984, balance: [180.0000000000-->] 0E-10, credit_limit: 2000.0000000000, email: None, email_opt_out: None row: 0x10a3cb050 session: 0x10a377ac0 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:44,002 - logic_logger - INF
429
+ Logic Phase: COMMIT LOGIC (session=0x10a377ac0) - 2025-10-24 08:44:44,002 - logic_logger - INF
430
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a377ac0) - 2025-10-24 08:44:44,002 - logic_logger - INF
431
+ ..Order[31] {AfterFlush Event} id: 31, notes: Test order - Ship Order Excludes from Balance, customer_id: 36, CreatedOn: 2025-10-24, date_shipped: [None-->] 2025-10-22 00:00:00, amount_total: 180.0000000000 row: 0x10a44ac50 session: 0x10a377ac0 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:44,002 - logic_logger - INF
432
+
433
+ ```
434
+ </details>
435
+
436
+ &nbsp;
437
+ &nbsp;
438
+ ### Scenario: Unship Order Includes in Balance
439
+ &emsp; Scenario: Unship Order Includes in Balance
440
+ &emsp;&emsp; Given Customer "Diana" with balance 0 and credit limit 5000
441
+ And Shipped order is created for "Diana" with 3 Gadget
442
+ &emsp;&emsp; When Order is unshipped
443
+ &emsp;&emsp; Then Customer balance should be 450
444
+ And Order amount_total should be 450
259
445
  <details markdown>
260
446
  <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
261
447
 
@@ -264,40 +450,69 @@ Logic Phase: AFTER_FLUSH LOGIC (session=0x10d61a7a0) - 2025-10-20
264
450
  &nbsp;
265
451
 
266
452
 
267
- **Rules Used** in Scenario: Change Product ID Re-copies Price # features/order_processing.feature:58
453
+ **Rules Used** in Scenario: Unship Order Includes in Balance
268
454
  ```
269
455
  Customer
270
- 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x10c5f8cc0>)
271
- Item
272
- 2. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
273
- 3. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
456
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
274
457
  Order
275
- 4. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
276
- 5. RowEvent Order.send_order_to_shipping()
458
+ 2. RowEvent Order.send_order_to_shipping()
277
459
  ```
278
- **Logic Log** in Scenario: Change Product ID Re-copies Price # features/order_processing.feature:58
460
+ **Logic Log** in Scenario: Unship Order Includes in Balance
279
461
  ```
280
462
 
281
- Change Product ID Re-copies Pric
282
- - 2025-10-20 19:17:15,051 - logic_logger - INF
463
+ Unship Order Includes in Balanc
464
+ - 2025-10-24 08:44:44,023 - logic_logger - INF
283
465
 
284
- Logic Phase: ROW LOGIC (session=0x10d61bac0) (sqlalchemy before_flush) - 2025-10-20 19:17:15,052 - logic_logger - INF
285
- ..Customer[50] {Update - client} id: 50, name: Jane 1761013035046, balance: 0E-10, credit_limit: 2000.0000000000, email: None, email_opt_out: None row: 0x10d8a1250 session: 0x10d61bac0 ins_upd_dlt: upd, initial: upd - 2025-10-20 19:17:15,052 - logic_logger - INF
286
- Logic Phase: COMMIT LOGIC (session=0x10d61bac0) - 2025-10-20 19:17:15,052 - logic_logger - INF
287
- Logic Phase: AFTER_FLUSH LOGIC (session=0x10d61bac0) - 2025-10-20 19:17:15,053 - logic_logger - INF
466
+ Logic Phase: ROW LOGIC (session=0x10a377240) (sqlalchemy before_flush) - 2025-10-24 08:44:44,025 - logic_logger - INF
467
+ ..Order[32] {Update - client} id: 32, notes: Test shipped order - Unship Order Includes in Balance, customer_id: 37, CreatedOn: 2025-10-24, date_shipped: [2025-10-22-->] None, amount_total: 450.0000000000 row: 0x10a3c9850 session: 0x10a377240 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:44,025 - logic_logger - INF
468
+ ....Customer[37] {Update - Adjusting customer: balance} id: 37, name: Diana 1761320684007, balance: [0E-10-->] 450.0000000000, credit_limit: 5000.0000000000, email: None, email_opt_out: None row: 0x10a3c8950 session: 0x10a377240 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:44,026 - logic_logger - INF
469
+ Logic Phase: COMMIT LOGIC (session=0x10a377240) - 2025-10-24 08:44:44,026 - logic_logger - INF
470
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a377240) - 2025-10-24 08:44:44,026 - logic_logger - INF
471
+ ..Order[32] {AfterFlush Event} id: 32, notes: Test shipped order - Unship Order Includes in Balance, customer_id: 37, CreatedOn: 2025-10-24, date_shipped: [2025-10-22-->] None, amount_total: 450.0000000000 row: 0x10a3c9850 session: 0x10a377240 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:44,026 - logic_logger - INF
288
472
 
289
473
  ```
290
474
  </details>
291
475
 
292
476
  &nbsp;
293
477
  &nbsp;
294
- ### Scenario: Multi-Item Order Total # features/order_processing.feature:67
478
+ ### Scenario: Exceed Credit Limit Rejected
479
+ &emsp; Scenario: Exceed Credit Limit Rejected
480
+ &emsp;&emsp; Given Customer "Silent" with balance 0 and credit limit 1000
481
+ &emsp;&emsp; When B2B order placed for "Silent" with 20 Widget
482
+ &emsp;&emsp; Then Order should be rejected
483
+ And Error message should contain "exceeds credit limit"
484
+ <details markdown>
485
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
486
+
487
+
488
+ &nbsp;
489
+ &nbsp;
490
+
491
+
492
+ **Rules Used** in Scenario: Exceed Credit Limit Rejected
493
+ ```
494
+ Customer
495
+ 1. Derive <class 'database.models.Customer'>.balance as Sum(Order.amount_total Where Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None) - <function declare_logic.<locals>.<lambda> at 0x109355260>)
496
+ 2. Constraint Function: None
497
+ Item
498
+ 3. Derive <class 'database.models.Item'>.unit_price as Copy(product.unit_price)
499
+ 4. Derive <class 'database.models.Item'>.amount as Formula (1): <function>
500
+ Order
501
+ 5. Derive <class 'database.models.Order'>.amount_total as Sum(Item.amount Where - None)
502
+ ```
503
+ **Logic Log** in Scenario: Exceed Credit Limit Rejected
504
+ ```
295
505
 
296
- &emsp; Scenario: Multi-Item Order Total
297
- &emsp;&emsp; **Given** Customer "Kevin" with balance 0 and credit limit 2000
298
- &emsp;&emsp; **When** B2B order placed for "Kevin" with 3 Widget and 2 Gadget
299
- &emsp;&emsp; **Then** Order amount_total should be 570
300
- &emsp;&emsp; **And** Customer "Kevin" balance should be 570
506
+ Exceed Credit Limit Rejecte
507
+ - 2025-10-24 08:44:44,036 - logic_logger - INF
508
+
509
+ Logic Phase: ROW LOGIC (session=0x10a377130) (sqlalchemy before_flush) - 2025-10-24 08:44:44,038 - logic_logger - INF
510
+ ..Customer[38] {Update - client} id: 38, name: Silent 1761320684031, balance: 0E-10, credit_limit: 1000.0000000000, email: None, email_opt_out: None row: 0x10a48c950 session: 0x10a377130 ins_upd_dlt: upd, initial: upd - 2025-10-24 08:44:44,038 - logic_logger - INF
511
+ Logic Phase: COMMIT LOGIC (session=0x10a377130) - 2025-10-24 08:44:44,038 - logic_logger - INF
512
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10a377130) - 2025-10-24 08:44:44,038 - logic_logger - INF
513
+
514
+ ```
515
+ </details>
301
516
 
302
517
  &nbsp;&nbsp;
303
- /Users/val/dev/ApiLogicServer/ApiLogicServer-dev/build_and_test/ApiLogicServer/basic_demo/test/api_logic_server_behave/behave_run.py completed at October 20, 2025 19:17:1
518
+ /Users/val/dev/ApiLogicServer/ApiLogicServer-dev/build_and_test/ApiLogicServer/basic_demo/test/api_logic_server_behave/behave_run.py completed at October 24, 2025 08:44:4