mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	Enhancement: allow specifying default currency for Monetary custom field (#7381)
This commit is contained in:
		@@ -525,7 +525,7 @@
 | 
				
			|||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">347</context>
 | 
					          <context context-type="linenumber">348</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="3768927257183755959" datatype="html">
 | 
					      <trans-unit id="3768927257183755959" datatype="html">
 | 
				
			||||||
@@ -544,7 +544,7 @@
 | 
				
			|||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">36</context>
 | 
					          <context context-type="linenumber">41</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html</context>
 | 
				
			||||||
@@ -584,7 +584,7 @@
 | 
				
			|||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">339</context>
 | 
					          <context context-type="linenumber">340</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html</context>
 | 
				
			||||||
@@ -718,7 +718,7 @@
 | 
				
			|||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">356</context>
 | 
					          <context context-type="linenumber">357</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
 | 
				
			||||||
@@ -1080,7 +1080,7 @@
 | 
				
			|||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">315</context>
 | 
					          <context context-type="linenumber">316</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
 | 
				
			||||||
@@ -1628,7 +1628,7 @@
 | 
				
			|||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">35</context>
 | 
					          <context context-type="linenumber">40</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html</context>
 | 
				
			||||||
@@ -3456,6 +3456,27 @@
 | 
				
			|||||||
          <context context-type="linenumber">20</context>
 | 
					          <context context-type="linenumber">20</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
 | 
					      <trans-unit id="2739003406164860877" datatype="html">
 | 
				
			||||||
 | 
					        <source>Default Currency</source>
 | 
				
			||||||
 | 
					        <context-group purpose="location">
 | 
				
			||||||
 | 
					          <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html</context>
 | 
				
			||||||
 | 
					          <context context-type="linenumber">33</context>
 | 
				
			||||||
 | 
					        </context-group>
 | 
				
			||||||
 | 
					      </trans-unit>
 | 
				
			||||||
 | 
					      <trans-unit id="7615210738790237590" datatype="html">
 | 
				
			||||||
 | 
					        <source>3-character currency code</source>
 | 
				
			||||||
 | 
					        <context-group purpose="location">
 | 
				
			||||||
 | 
					          <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html</context>
 | 
				
			||||||
 | 
					          <context context-type="linenumber">33</context>
 | 
				
			||||||
 | 
					        </context-group>
 | 
				
			||||||
 | 
					      </trans-unit>
 | 
				
			||||||
 | 
					      <trans-unit id="607636736207886379" datatype="html">
 | 
				
			||||||
 | 
					        <source>Use locale</source>
 | 
				
			||||||
 | 
					        <context-group purpose="location">
 | 
				
			||||||
 | 
					          <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html</context>
 | 
				
			||||||
 | 
					          <context context-type="linenumber">33</context>
 | 
				
			||||||
 | 
					        </context-group>
 | 
				
			||||||
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="528950215505228201" datatype="html">
 | 
					      <trans-unit id="528950215505228201" datatype="html">
 | 
				
			||||||
        <source>Create new custom field</source>
 | 
					        <source>Create new custom field</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
@@ -5874,14 +5895,14 @@
 | 
				
			|||||||
        <source>Content</source>
 | 
					        <source>Content</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">211</context>
 | 
					          <context context-type="linenumber">212</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="218403386307979629" datatype="html">
 | 
					      <trans-unit id="218403386307979629" datatype="html">
 | 
				
			||||||
        <source>Metadata</source>
 | 
					        <source>Metadata</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">220</context>
 | 
					          <context context-type="linenumber">221</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts</context>
 | 
				
			||||||
@@ -5892,119 +5913,119 @@
 | 
				
			|||||||
        <source>Date modified</source>
 | 
					        <source>Date modified</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">227</context>
 | 
					          <context context-type="linenumber">228</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="6392918669949841614" datatype="html">
 | 
					      <trans-unit id="6392918669949841614" datatype="html">
 | 
				
			||||||
        <source>Date added</source>
 | 
					        <source>Date added</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">231</context>
 | 
					          <context context-type="linenumber">232</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="146828917013192897" datatype="html">
 | 
					      <trans-unit id="146828917013192897" datatype="html">
 | 
				
			||||||
        <source>Media filename</source>
 | 
					        <source>Media filename</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">235</context>
 | 
					          <context context-type="linenumber">236</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="4500855521601039868" datatype="html">
 | 
					      <trans-unit id="4500855521601039868" datatype="html">
 | 
				
			||||||
        <source>Original filename</source>
 | 
					        <source>Original filename</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">239</context>
 | 
					          <context context-type="linenumber">240</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="7985558498848210210" datatype="html">
 | 
					      <trans-unit id="7985558498848210210" datatype="html">
 | 
				
			||||||
        <source>Original MD5 checksum</source>
 | 
					        <source>Original MD5 checksum</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">243</context>
 | 
					          <context context-type="linenumber">244</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="5888243105821763422" datatype="html">
 | 
					      <trans-unit id="5888243105821763422" datatype="html">
 | 
				
			||||||
        <source>Original file size</source>
 | 
					        <source>Original file size</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">247</context>
 | 
					          <context context-type="linenumber">248</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="2696647325713149563" datatype="html">
 | 
					      <trans-unit id="2696647325713149563" datatype="html">
 | 
				
			||||||
        <source>Original mime type</source>
 | 
					        <source>Original mime type</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">251</context>
 | 
					          <context context-type="linenumber">252</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="342875990758166588" datatype="html">
 | 
					      <trans-unit id="342875990758166588" datatype="html">
 | 
				
			||||||
        <source>Archive MD5 checksum</source>
 | 
					        <source>Archive MD5 checksum</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">256</context>
 | 
					          <context context-type="linenumber">257</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="6033581412811562084" datatype="html">
 | 
					      <trans-unit id="6033581412811562084" datatype="html">
 | 
				
			||||||
        <source>Archive file size</source>
 | 
					        <source>Archive file size</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">262</context>
 | 
					          <context context-type="linenumber">263</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="6992781481378431874" datatype="html">
 | 
					      <trans-unit id="6992781481378431874" datatype="html">
 | 
				
			||||||
        <source>Original document metadata</source>
 | 
					        <source>Original document metadata</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">271</context>
 | 
					          <context context-type="linenumber">272</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="2846565152091361585" datatype="html">
 | 
					      <trans-unit id="2846565152091361585" datatype="html">
 | 
				
			||||||
        <source>Archived document metadata</source>
 | 
					        <source>Archived document metadata</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">274</context>
 | 
					          <context context-type="linenumber">275</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="1295614462098694869" datatype="html">
 | 
					      <trans-unit id="1295614462098694869" datatype="html">
 | 
				
			||||||
        <source>Preview</source>
 | 
					        <source>Preview</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">281</context>
 | 
					          <context context-type="linenumber">282</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="7206723502037428235" datatype="html">
 | 
					      <trans-unit id="7206723502037428235" datatype="html">
 | 
				
			||||||
        <source>Notes <x id="START_BLOCK_IF" equiv-text="@if (document?.notes.length) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="<span class="badge text-bg-secondary ms-1">"/><x id="INTERPOLATION" equiv-text="ngth}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source>
 | 
					        <source>Notes <x id="START_BLOCK_IF" equiv-text="@if (document?.notes.length) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="<span class="badge text-bg-secondary ms-1">"/><x id="INTERPOLATION" equiv-text="ngth}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">293,296</context>
 | 
					          <context context-type="linenumber">294,297</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="186236568870281953" datatype="html">
 | 
					      <trans-unit id="186236568870281953" datatype="html">
 | 
				
			||||||
        <source>History</source>
 | 
					        <source>History</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">304</context>
 | 
					          <context context-type="linenumber">305</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="5129524307369213584" datatype="html">
 | 
					      <trans-unit id="5129524307369213584" datatype="html">
 | 
				
			||||||
        <source>Save & next</source>
 | 
					        <source>Save & next</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">341</context>
 | 
					          <context context-type="linenumber">342</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="4910102545766233758" datatype="html">
 | 
					      <trans-unit id="4910102545766233758" datatype="html">
 | 
				
			||||||
        <source>Save & close</source>
 | 
					        <source>Save & close</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">344</context>
 | 
					          <context context-type="linenumber">345</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="8191371354890763172" datatype="html">
 | 
					      <trans-unit id="8191371354890763172" datatype="html">
 | 
				
			||||||
        <source>Enter Password</source>
 | 
					        <source>Enter Password</source>
 | 
				
			||||||
        <context-group purpose="location">
 | 
					        <context-group purpose="location">
 | 
				
			||||||
          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
					          <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
 | 
				
			||||||
          <context context-type="linenumber">395</context>
 | 
					          <context context-type="linenumber">396</context>
 | 
				
			||||||
        </context-group>
 | 
					        </context-group>
 | 
				
			||||||
      </trans-unit>
 | 
					      </trans-unit>
 | 
				
			||||||
      <trans-unit id="2218903673684131427" datatype="html">
 | 
					      <trans-unit id="2218903673684131427" datatype="html">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,12 @@ const customFields: CustomField[] = [
 | 
				
			|||||||
      select_options: ['Option 1', 'Option 2', 'Option 3'],
 | 
					      select_options: ['Option 1', 'Option 2', 'Option 3'],
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    id: 5,
 | 
				
			||||||
 | 
					    name: 'Field 5',
 | 
				
			||||||
 | 
					    data_type: CustomFieldDataType.Monetary,
 | 
				
			||||||
 | 
					    extra_data: { default_currency: 'JPY' },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
const document: Document = {
 | 
					const document: Document = {
 | 
				
			||||||
  id: 1,
 | 
					  id: 1,
 | 
				
			||||||
@@ -112,6 +118,18 @@ describe('CustomFieldDisplayComponent', () => {
 | 
				
			|||||||
    expect(component.value).toEqual(100)
 | 
					    expect(component.value).toEqual(100)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should respect explicit default currency', () => {
 | 
				
			||||||
 | 
					    component['defaultCurrencyCode'] = 'EUR' // mock default locale injection
 | 
				
			||||||
 | 
					    component.fieldId = 5
 | 
				
			||||||
 | 
					    component.document = {
 | 
				
			||||||
 | 
					      id: 1,
 | 
				
			||||||
 | 
					      title: 'Doc 1',
 | 
				
			||||||
 | 
					      custom_fields: [{ field: 5, document: 1, created: null, value: '100' }],
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    expect(component.currency).toEqual('JPY')
 | 
				
			||||||
 | 
					    expect(component.value).toEqual(100)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('should show select value', () => {
 | 
					  it('should show select value', () => {
 | 
				
			||||||
    expect(component.getSelectValue(customFields[3], 2)).toEqual('Option 3')
 | 
					    expect(component.getSelectValue(customFields[3], 2)).toEqual('Option 3')
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,7 +90,9 @@ export class CustomFieldDisplayComponent implements OnInit, OnDestroy {
 | 
				
			|||||||
    )?.value
 | 
					    )?.value
 | 
				
			||||||
    if (this.value && this.field.data_type === CustomFieldDataType.Monetary) {
 | 
					    if (this.value && this.field.data_type === CustomFieldDataType.Monetary) {
 | 
				
			||||||
      this.currency =
 | 
					      this.currency =
 | 
				
			||||||
        this.value.match(/([A-Z]{3})/)?.[0] ?? this.defaultCurrencyCode
 | 
					        this.value.match(/([A-Z]{3})/)?.[0] ??
 | 
				
			||||||
 | 
					        this.field.extra_data?.default_currency ??
 | 
				
			||||||
 | 
					        this.defaultCurrencyCode
 | 
				
			||||||
      this.value = parseFloat(this.value.replace(this.currency, ''))
 | 
					      this.value = parseFloat(this.value.replace(this.currency, ''))
 | 
				
			||||||
    } else if (
 | 
					    } else if (
 | 
				
			||||||
      this.value?.length &&
 | 
					      this.value?.length &&
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,11 @@
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        @case (CustomFieldDataType.Monetary) {
 | 
				
			||||||
 | 
					          <div class="my-3">
 | 
				
			||||||
 | 
					            <pngx-input-text i18n-title title="Default Currency" hint="3-character currency code" i18n-hint formControlName="default_currency" placeholder="Use locale" i18n-placeholder autocomplete="off"></pngx-input-text>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,6 +90,7 @@ export class CustomFieldEditDialogComponent
 | 
				
			|||||||
      data_type: new FormControl(null),
 | 
					      data_type: new FormControl(null),
 | 
				
			||||||
      extra_data: new FormGroup({
 | 
					      extra_data: new FormGroup({
 | 
				
			||||||
        select_options: new FormArray([new FormControl(null)]),
 | 
					        select_options: new FormArray([new FormControl(null)]),
 | 
				
			||||||
 | 
					        default_currency: new FormControl(null),
 | 
				
			||||||
      }),
 | 
					      }),
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,11 @@ describe('MonetaryComponent', () => {
 | 
				
			|||||||
    expect(component.defaultCurrencyCode).toEqual('BRL')
 | 
					    expect(component.defaultCurrencyCode).toEqual('BRL')
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should support setting a default currency code', () => {
 | 
				
			||||||
 | 
					    component.defaultCurrency = 'EUR'
 | 
				
			||||||
 | 
					    expect(component.defaultCurrencyCode).toEqual('EUR')
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('should parse monetary value correctly', () => {
 | 
					  it('should parse monetary value correctly', () => {
 | 
				
			||||||
    expect(component['parseMonetaryValue']('123.4')).toEqual('123.4')
 | 
					    expect(component['parseMonetaryValue']('123.4')).toEqual('123.4')
 | 
				
			||||||
    expect(component['parseMonetaryValue']('123.4', true)).toEqual('123.40')
 | 
					    expect(component['parseMonetaryValue']('123.4', true)).toEqual('123.40')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { Component, forwardRef, Inject, LOCALE_ID } from '@angular/core'
 | 
					import { Component, forwardRef, Inject, Input, LOCALE_ID } from '@angular/core'
 | 
				
			||||||
import { NG_VALUE_ACCESSOR } from '@angular/forms'
 | 
					import { NG_VALUE_ACCESSOR } from '@angular/forms'
 | 
				
			||||||
import { AbstractInputComponent } from '../abstract-input'
 | 
					import { AbstractInputComponent } from '../abstract-input'
 | 
				
			||||||
import { getLocaleCurrencyCode } from '@angular/common'
 | 
					import { getLocaleCurrencyCode } from '@angular/common'
 | 
				
			||||||
@@ -29,11 +29,16 @@ export class MonetaryComponent extends AbstractInputComponent<string> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  defaultCurrencyCode: string
 | 
					  defaultCurrencyCode: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Input()
 | 
				
			||||||
 | 
					  set defaultCurrency(currency: string) {
 | 
				
			||||||
 | 
					    if (currency) this.defaultCurrencyCode = currency
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(@Inject(LOCALE_ID) currentLocale: string) {
 | 
					  constructor(@Inject(LOCALE_ID) currentLocale: string) {
 | 
				
			||||||
    super()
 | 
					    super()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.currency = this.defaultCurrencyCode =
 | 
					    this.currency = this.defaultCurrencyCode =
 | 
				
			||||||
      getLocaleCurrencyCode(currentLocale)
 | 
					      this.defaultCurrency ?? getLocaleCurrencyCode(currentLocale)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  writeValue(newValue: any): void {
 | 
					  writeValue(newValue: any): void {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="position-relative" [class.col-md-9]="horizontal">
 | 
					      <div class="position-relative" [class.col-md-9]="horizontal">
 | 
				
			||||||
        <input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [disabled]="disabled" [autocomplete]="autocomplete">
 | 
					        <input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [disabled]="disabled" [autocomplete]="autocomplete" [placeholder]="placeholder">
 | 
				
			||||||
        @if (hint) {
 | 
					        @if (hint) {
 | 
				
			||||||
          <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
 | 
					          <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,9 @@ export class TextComponent extends AbstractInputComponent<string> {
 | 
				
			|||||||
  @Input()
 | 
					  @Input()
 | 
				
			||||||
  autocomplete: string
 | 
					  autocomplete: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Input()
 | 
				
			||||||
 | 
					  placeholder: string = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
    super()
 | 
					    super()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,6 +157,7 @@
 | 
				
			|||||||
                    @case (CustomFieldDataType.Monetary) {
 | 
					                    @case (CustomFieldDataType.Monetary) {
 | 
				
			||||||
                      <pngx-input-monetary formControlName="value"
 | 
					                      <pngx-input-monetary formControlName="value"
 | 
				
			||||||
                      [title]="getCustomFieldFromInstance(fieldInstance)?.name"
 | 
					                      [title]="getCustomFieldFromInstance(fieldInstance)?.name"
 | 
				
			||||||
 | 
					                      [defaultCurrency]="getCustomFieldFromInstance(fieldInstance)?.extra_data?.default_currency"
 | 
				
			||||||
                      [removable]="userIsOwner"
 | 
					                      [removable]="userIsOwner"
 | 
				
			||||||
                      (removed)="removeField(fieldInstance)"
 | 
					                      (removed)="removeField(fieldInstance)"
 | 
				
			||||||
                      [horizontal]="true"
 | 
					                      [horizontal]="true"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,5 +57,6 @@ export interface CustomField extends ObjectWithId {
 | 
				
			|||||||
  created?: Date
 | 
					  created?: Date
 | 
				
			||||||
  extra_data?: {
 | 
					  extra_data?: {
 | 
				
			||||||
    select_options?: string[]
 | 
					    select_options?: string[]
 | 
				
			||||||
 | 
					    default_currency?: string
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -507,6 +507,23 @@ class CustomFieldSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
            raise serializers.ValidationError(
 | 
					            raise serializers.ValidationError(
 | 
				
			||||||
                {"error": "extra_data.select_options must be a valid list"},
 | 
					                {"error": "extra_data.select_options must be a valid list"},
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					        elif (
 | 
				
			||||||
 | 
					            "data_type" in attrs
 | 
				
			||||||
 | 
					            and attrs["data_type"] == CustomField.FieldDataType.MONETARY
 | 
				
			||||||
 | 
					            and "extra_data" in attrs
 | 
				
			||||||
 | 
					            and "default_currency" in attrs["extra_data"]
 | 
				
			||||||
 | 
					            and attrs["extra_data"]["default_currency"] is not None
 | 
				
			||||||
 | 
					            and (
 | 
				
			||||||
 | 
					                not isinstance(attrs["extra_data"]["default_currency"], str)
 | 
				
			||||||
 | 
					                or (
 | 
				
			||||||
 | 
					                    len(attrs["extra_data"]["default_currency"]) > 0
 | 
				
			||||||
 | 
					                    and len(attrs["extra_data"]["default_currency"]) != 3
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
 | 
					            raise serializers.ValidationError(
 | 
				
			||||||
 | 
					                {"error": "extra_data.default_currency must be a 3-character string"},
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        return super().validate(attrs)
 | 
					        return super().validate(attrs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,6 +137,66 @@ class TestCustomFieldsAPI(DirectoriesMixin, APITestCase):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
 | 
					        self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_create_custom_field_monetary_validation(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        GIVEN:
 | 
				
			||||||
 | 
					            - Custom field does not exist
 | 
				
			||||||
 | 
					        WHEN:
 | 
				
			||||||
 | 
					            - API request to create custom field with invalid default currency option
 | 
				
			||||||
 | 
					            - API request to create custom field with valid default currency option
 | 
				
			||||||
 | 
					        THEN:
 | 
				
			||||||
 | 
					            - HTTP 400 is returned
 | 
				
			||||||
 | 
					            - HTTP 201 is returned
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # not a string
 | 
				
			||||||
 | 
					        resp = self.client.post(
 | 
				
			||||||
 | 
					            self.ENDPOINT,
 | 
				
			||||||
 | 
					            json.dumps(
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "data_type": "monetary",
 | 
				
			||||||
 | 
					                    "name": "Monetary Field",
 | 
				
			||||||
 | 
					                    "extra_data": {
 | 
				
			||||||
 | 
					                        "default_currency": 123,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            content_type="application/json",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # not a 3-letter currency code
 | 
				
			||||||
 | 
					        resp = self.client.post(
 | 
				
			||||||
 | 
					            self.ENDPOINT,
 | 
				
			||||||
 | 
					            json.dumps(
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "data_type": "monetary",
 | 
				
			||||||
 | 
					                    "name": "Monetary Field",
 | 
				
			||||||
 | 
					                    "extra_data": {
 | 
				
			||||||
 | 
					                        "default_currency": "EU",
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            content_type="application/json",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # valid currency code
 | 
				
			||||||
 | 
					        resp = self.client.post(
 | 
				
			||||||
 | 
					            self.ENDPOINT,
 | 
				
			||||||
 | 
					            json.dumps(
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "data_type": "monetary",
 | 
				
			||||||
 | 
					                    "name": "Monetary Field",
 | 
				
			||||||
 | 
					                    "extra_data": {
 | 
				
			||||||
 | 
					                        "default_currency": "EUR",
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            content_type="application/json",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(resp.status_code, status.HTTP_201_CREATED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_custom_field_instance(self):
 | 
					    def test_create_custom_field_instance(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        GIVEN:
 | 
					        GIVEN:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user