7.2 KiB
Measurement Workflows
Part of
Nop.Plugin.Misc.FruitBankPlugin. SeeREADME.mdfor project overview. For entity model seedocs/DOMAIN_MODEL.md. For SignalR endpoints seedocs/SIGNALR/README.md. For core measurement system rules and common domain traps, see:../../../../../FruitBankHybridApp/FruitBank.Common/docs/GLOSSARY.md
Three parallel measurement workflows share the same weight formula and MeasuringStatus lifecycle.
Shared concepts (canonical in DOMAIN_MODEL.md)
These are defined once in DOMAIN_MODEL.md — referenced here, not duplicated:
- Weight formula —
NetWeight = GrossWeight − PalletWeight − (TrayQuantity × TareWeight). See DOMAIN_MODEL.md § Weight Formula for field meanings and edge cases. - MeasuringStatus lifecycle —
NotStarted (0) → Started (10) → Finnished (20) → Audited (30). See DOMAIN_MODEL.md § MeasuringStatus Lifecycle for state transitions. Note:Finnishedis an intentional double-n typo — do not "fix" it. - IsMeasurable Flag —
ProductDto.IsMeasurablemaster toggle for weight validation. See DOMAIN_MODEL.md § IsMeasurable Flag forfalse-branch semantics.
Workflow 1: Inbound Shipping
Supplier truck arrives at the warehouse. Goods are weighed and compared to the delivery document.
Shipping (truck)
→ ShippingDocument (supplier delivery note)
→ ShippingItem (product line)
→ ShippingItemPallet (individual measurement)
Flow
- Create Shipping — truck registration (LicencePlate, ShippingDate, CargoCompany)
- Add ShippingDocument — link to Partner (supplier), upload PDF delivery note
- Add ShippingItem — product line from document.
IsMeasurablecopied fromProductDto.IsMeasurable - Weigh pallets —
FruitBankDataController.AddOrUpdateMeasuredShippingItemPallet()- Each pallet: GrossWeight, PalletWeight, TareWeight, TrayQuantity → NetWeight (formula in Shared concepts above)
- Cascade update — after each pallet measurement:
ShippingItem: MeasuredGrossWeight, MeasuredNetWeight, MeasuredQuantity recalculated from palletsShippingDocument.IsAllMeasured= all items measuredShipping.IsAllMeasured= all documents measured- Product
AverageWeightupdated from measured data
Event Cascade (FruitBankEventConsumer)
ShippingItemPallet deleted → ShippingItem measuring values refreshed
ShippingItem inserted/updated → ShippingDocument.IsAllMeasured rechecked
ShippingDocument inserted/updated → Shipping.IsAllMeasured rechecked
Shipping deleted → cascade delete ShippingDocuments
ShippingDocument deleted → cascade delete ShippingItems
ShippingItem deleted → cascade delete ShippingItemPallets
ShippingItem: Declared vs Measured
| Declared (from document) | Measured (warehouse) | Discrepancy tracked |
|---|---|---|
QuantityOnDocument |
MeasuredQuantity |
Yes |
GrossWeightOnDocument |
MeasuredGrossWeight |
Yes |
NetWeightOnDocument |
MeasuredNetWeight |
Yes |
Workflow 2: Outbound Order
Customer order is prepared. Items are weighed before dispatch.
OrderDto (order)
→ OrderItemDto (line item)
→ OrderItemPallet (measurement record)
Flow
- Start Measuring —
CustomOrderSignalREndpoint.StartMeasuring(orderId, userId)- Sets
MeasurementOwnerIdvia GenericAttribute - Order status set to Processing, Payment to Pending
- Broadcasts
SendOrderChanged
- Sets
- Weigh pallets —
CustomOrderSignalREndpoint.AddOrUpdateMeasuredOrderItemPallet()- Same weight formula as shipping
- Triggers price recalculation after each pallet
- Broadcasts
SendOrderItemPalletChanged
- Complete order —
CustomOrderSignalREndpoint.SetOrderStatusToComplete(orderId, revisorId)- Validates: all order items must have pallets
- Recalculates final prices v<>!I<><49>e<A4>vü<76>q<0C><03>|<7C><>-<2D><><8F><07>0
.
8à p<>ʳ<A1>B<86>0 <04>à<85>800<30>Ha@@À l<><6C>!!Aa<14> G<>p <08>c<C3>k<><6B><B7> <20> <06><02>G<C8>j<FE><6A><AF>J<E1>.W<><57>B<B5>E<8A>Tz<54><7A><89><0F><>z<93>2g<32><04>xeF<65><46><AF>H<D1>0<AC><30><F8>h)<29>!<04>J<<3C> ew<><77><A7>0 *<2A><>B`` <01>p,f<>I<B1><49><9F>DC<12>\(<28>H<D1>B<9B>p<03>@p(dq<64> PB<><42>.<2E><08><><A7>@ <02>pjqJ<71>C <20>@F<><46>@.<2E><08>!<0C><><83>0paʗ<61><CA97>P,"<22><><91>!<21>,.<2E>H<02>0D Pl<> *E<>($<04>0 .<2E>Ȝ<E1>a@<04><>0f<><66><81><8A><02>((<02> ,<2C>Ȁ<E1><C880>00<02><><84>0j<><6A><A1><8A> <20>0<05><>p(,<2C><>"<01>@<02>@p0j<>J<B1><4A><8E>@ <10>*<2A><08><><9B><03><81><8A>3<81><80>@8<04><>@p@.ш<> 8<03>18f<>J<02><01> *ሚA<E1889A>A<> fQ<66><16>"a@<04>Dbp@(*<2A><> <01> 0d<><64><04><>P<07>@0 *<2A>Ȟ P<02><>@0j<><6A><81>C<B8> A<>p8.<01><01><> <01>@l<>J!Da8<04>B<83>,ш<><D188><BC> <02>P d<> <0A><><92>p( <05>!A,<2C>H0<48>a Àh<>ʙCA<0C><>@A( 2<>HA<>p8 <20><><02>Ph<><68>#Aa<41>@<0E><>,<2C>ȏBaP(<0C><><82>0la<6C><1B>"<22>X8 <02>A880<11> B<>0(@ P0h<>J<B1><04><><0E>2<><08><><80>@<10>"<22>l<>ʻ<C1><CABB>PH<02>Ba00<>ȭ<F1><C8AD> H <0A><>a8n<><6E>6<CA>A1X C!!H2<>ȇ<F1>aP<06>a<84>8(p<>J <09><01>88.<11><>@`` <0C>Ba@ <20>p<EFBFBD><70>D<>P,E<><45>@6<11><><02>P8 C<>@0ra <08><>P80! <02><><02>@(tK<><4B>a@ <0A><>a6!<21><><02>00<02><01><10><><EFBFBD><82>=<02>p<10>C<>8 8A<38><02>0 <04><> <20><08>x1C(<07><>02!<21><01>P(<0C><><85>P8x!<21><><8B>pH <04>P8 2A<32><41>Aa <06> <08>A<82><08>"C<>@2QɞA<C99E>0<06>@t<> =<03>p0<0C>A<88><41>0L! <09><><B1><82>X<04><><85>H<14><>ʤ<E1>E<03>, <20>A<82>PD:!<21><><01>p C<01>($<24>A<94><13><02>(<04><>"q$4A<34><17>aP@(<14>q<05>0<08><><82>0P<B<F1888781>h4<16><04><>h,<2C>1<94>Bq<16><><96><11><>!<21><><04><>H <05>@<40>(<14><01>0Ă<12> <10>C<83><12>K<89>p <0E><02>Dm<44>پ<93><D9BE>K B<>4$*<2A><>R<C2>ń<<3C><>E<E3>.:?R<><52><BD><9E>E<98>&<26>f<CD>20<><:<3A>z<95> <RI<52><49>z1<7A><31>AIT <20><><AC>Ty0!<02>ʂ8(41<34>0yd<79>HR<48> <0A>@0<H<A4>r<CA>L<CE>>T<><54><F3><C9><CB><08>FȦ<46><C8A6>zQ<7A>̋10<10>_X<5F><58><FD><9E><04>Gq<><71>P<C4>e<11><>U<D9><55><A9><EB>Q<>tN <20><><98><EB> <0A>%<25>^[<5B>V[<5B>f<FE><66>l<8D>;<3B>\<0C><><E6>(Ff <0A><>,~2"<22>߅<03><><B3>P<98><50>H3<48>d8<11><>G<EE><47><C1><B1>f<BC> ȴ<>T.<CC>h<E3>h@6<>&<26>Al./<2F><><88><83>|4<>Ȥ<14>x:5<><35>m<9F><03><>F,<2C><18>@%n<><6E>'r94d<0C><>p|D<>ymeP<65>R<AC><52> qJ<71><4A>-<2D>$<24><><F3>N<B0><4E><8C><87>p@,<2C><><1D><>SYf<16><><97>Y<10><>,<2C><><13>p:%Ke<4B>X, <20>$<24><><9B>u <03>(<28><><B1> <0A> 2 <09><> <20>J<87>c<86>p.n3L<33>o<><6F><9F><DF>x:<0C><>(<D5>R<<1C>z<FE><7A><B7>V<EE>ܡ:<3A><><F2><C9>rq<72>Zäen- <20><>~<7E><><85><B2>><3E><><8C><16>m <20><>ɇcC<1A>v<9D><76><F2><CB><CB><06>i<89><69><D7>˄ <09><>#qH<02><>a0*B<0B>p<94>h<07><>h <1C><><8A><92> 6<>F<1F><>:<3A>D<99>t<8C><74><8C><81><C0>z<BB>O<B3><4F>'[<5B>TԁM?<3F><>8 <02><><87>00@<40>"ՓÑ1,<1E>ƀ<92>yh<79> <20>F<B4><46><83>8E4<E0><D2>Դh<><68>x2 <09><>AXP<58><50><0C><05>p, a<> 4<><02>O<><4F>pd0O<><11>(<28>A<C6>A<>P<04>q<1C>2UBP<42><14>K#<02>\<5C><> <20>D<8E>P$<16><>"<22>h <1C><><03>CBhP"<22><>R<>x<E9>!<03>@Y,<05><>q@<<<03>&<26>!PX(<08>AdD<>Q<EC>AA0$<16><>C1 <ӗ3<D397>e2<65>(0<><30>ñT<C3B1>!<0E><>d<C5>h0<0F><><86>xB<78><42><A3><04><> 8<1A>D<86><44><18>A<F2><41><8E><95>Q<07>r`HN<48>X<01>"<92>I<81><A2>(0<02>N<82><4E>B<86>h <0A>@<40><>,LS<18><>%<25><>h8<68>J$3X<><58>&<26><>P <0A>EAqj#ٛ<><D99B><88>p8&<11>g<83><67>l<D9><6C><F8><04>ap <0A><>A<C5>8 lS<6C> <0A><>,"<22>ƅ<03>\<5C>Ošp0(<04><>aqPh<03>&L<>r<E7><" цs ]<02><0E><>bpP8<0E><><8D><C1>p$h<03>D<>aJb<4A><62>DbOA<>X<07>!H<0C>Sڏ<05><><83>L("<22><>S1R<><52><8F>a0H,C<><43><18><><EFBFBD><8E><83>ñ<>\ <0A>b<C7>Tb<0F>D<A9>A80<10>Ca<43>@8<>cZ.<2E>E<8E><45>p0 <0A><>3<85>HRϣE`<60>@, <0A><>pP$<24><>Z<C3>Ga<47>A8<1E><>d"y<14><><0E><>2)D<13><04>P <20><1A>ʠ<BA><CAA0>0c<><63> O<1C>A<C5>(@ b@ <08><><8E>=F<>"YD <09><><C1>(<28><>a9I$<24>H( <08><>Z<><16><>7<AF><37>v7ݍ<37>r <20>c<BE>ƀ00$"<22>\<5C><>~<12>|<>@ <<+_<>Y<F2><59><CC>.<2E>t8
<CA>T & <16>l<13><><E9>T<1F>"@<0C><>Q<B0>F<><46>H$ <0B><><85>0H<30>2ԧ<32> <20>X,<02>D<><44>t܁<74><07><><84>p<04>H<8B><48>xTS<><90>,<16>ɦsB<73><42>aE<CE82>PE!<21><>(Lӗ<0B>Cs<43>D& H<>CI<43><49><81>(<28>(s<>(<28><><8B><81><E1>L6CT<43>T<E4><54><B8>f<F5>IB<49><42><A5>4<04><>A@<A0><86><C5>#y46<34><36><15>G<93><10>q<E1>c<C5>8M><3E><><AB>c <20>t*]<0E><>&<26>(<04><> <20>~<><7F><9F>U#D9 r<>A<8A><41>Z<11>F<95><46><99>0*<2A>c<8A>5a"<22><05><><D7><D4>A(Ȕ҃<>&<26><>p:<3A><><DF>4><3E>t<8D><74>õ<17>B<B5><42><AB>X<B4><58><CD><CE><EF>3܁<33><DC81>Ѹx*<2A>І<99>᪽kƁA<C681>d<1C><>&<26><>l,<2C>#<23><>ZN<5A><4E>6<>ь<9D>s͛}<7D><><0F>r 2<><32><A6><CB><E9>Z<>v[<5B>><3E><><9A><91><E2>l<12><>*|Ng˹J$<24><><84>p#N<><19>,<2C><>8<11>ti R5<19>Ч<BC><D0A7>n(N<>SQr<><72> mc<6D>D<04>@00$<24><>V<83><56><F4><EE><1C><><8B><16><0B>T<BC><54>!<21>2̈́A@<14>"
<<13>
y=<3D>+<14>p*h<>ɖ<D1><C996> <02>dR<64>L<91>a̒<61>Q<>D<04>V#<23>q <09>ˤ<B4><06><><81> ڱ<>(<28>̅ B @X$J<> <09><><BA>
<03><18><><EFBFBD><A8><A1><05><>`P$F<><46>VQ <05>p <20><02><>A<EFBFBD>X<14>A<17>"r8<10>B<02>q8<71><38>I@ <AF>$sX"<22><15> (L<>g<86>:<3A>f<9D>ϼ<A7><CFBC>|<7C>